Pierwsza recenzja Alice Code

20

Alice jest stażystką w firmie, która używa Brainfuck jako podstawowego języka do programowania zarówno po stronie klienta, jak i serwera. Alice właśnie napisała swój pierwszy kod i trochę się denerwuje, przygotowując się do pierwszej recenzji kodu.

Alice chce, aby kod był odpowiednio sformatowany i wyglądał ładnie, ale nie ma czasu na zapoznanie się z 328-stronicowym przewodnikiem po stylu kodu firmy, więc postanowiła sformatować go jako idealny kwadrat . Niestety, długość kodu może być niewystarczająca do utworzenia kwadratu, więc postanowiła pozostawić prostokątną przerwę na środku. Luki muszą być idealnie wyśrodkowane i możliwie jak najbliżej kwadratu .

Przykłady

++++++         +++++         +++++         +++++         +++++         +++++
++++++         +++++         +++++         +  ++         ++ ++         +++++
++++++         ++ ++         +   +         +  ++         +   +
++++++         +++++         +++++         +++++         ++ ++         +++++
++++++         +++++         +++++         +++++         +++++         +++++

Perfect         OK         Acceptable   Unacceptable    No way!        Nope.

Napisz program lub funkcję, która pomoże Alice. Biorąc pod uwagę kod Alice jako ciąg wejściowy, w miarę możliwości wyślij poprawnie sformatowany kod, jak opisano poniżej. Jeśli formatowanie jest niemożliwe, wyjdź płaczącą emoji :~(.

To jest więc odpowiedzi są punktowane w bajtach, a celem jest mniejsza liczba bajtów.

Ograniczenia

  1. Twój program lub funkcja powinna przyjmować pojedynczy ciąg znaków jako dane wejściowe i wyprowadzać jeden lub więcej wierszy tekstu (lub zwracać ciąg wielu wierszy lub tablicę ciągów, jeśli zaimplementujesz funkcję).
  2. Łańcuch wejściowy może zawierać dowolne znaki ASCII, w tym spacje.
  3. Wszystkie białe znaki na wejściu należy zignorować. Nie powinny one liczyć się do długości kodu i nie powinny być używane w danych wyjściowych.
  4. Łańcuch wejściowy zawiera co najmniej jeden znak spacji.
  5. Sformatowany kod musi mieć te same znaki spacji w tej samej kolejności, co w kodzie wejściowym.
  6. Sformatowany kod musi być doskonałym kwadratem, tzn. Wszystkie linie powinny mieć tę samą długość, a liczba linii powinna być równa długości linii.
  7. Sformatowany kod może zawierać przerwę w środku.
  8. W odstępie można stosować tylko znaki spacji (kod ASCII 32).
  9. Przerwa (jeśli występuje) musi być prostokątna.
  10. Każdy wiersz sformatowanego kodu musi zawierać co najmniej jeden znak spacji, tzn. Szerokość przerwy musi być ściśle mniejsza niż szerokość kwadratu (przerwa 5x1 jest niedopuszczalna dla kwadratu 5x5).
  11. Odstęp powinien być poziomy, tzn. Szerokość odstępu powinna być większa lub równa wysokości odstępu.
  12. Luka musi być idealnie wyśrodkowana.
  13. W związku z tym parzystość szerokości i wysokości parzystości powinna być taka sama jak parzystość szerokości kwadratu (na przykład dla 5x5 odstępu kwadratowego może wynosić 1x1, 3x1 lub 3x3).
  14. Jeśli to możliwe, generuj kwadrat bez żadnej przerwy.
  15. W przypadku wielu rozwiązań wybierz jedno z odstępem najbliższym kwadratowi, tzn. Różnica między szerokością odstępu a wysokością odstępu jest minimalna (na przykład: odstęp 10x10 jest bardziej preferowany niż 8x6, a 8x6 jest bardziej korzystny niż 6x2).
  16. Jeśli nadal występuje remis, wybierz rozwiązanie o minimalnej powierzchni przerwy (na przykład przerwa 2x2 jest bardziej preferowana niż 4x4).
  17. Jeśli w ogóle nie można sformatować kodu, wyjdź :~(.
  18. Nowa linia po ostatniej linii jest opcjonalna.
  19. [Nowość] Możesz bezpiecznie założyć, że każdy znak o kodzie poniżej 33 to biała spacja. Mam nadzieję, że pomoże ci to w grze w golfa.

Testy

Input           Output      Code length     Comment

+++++++++       +++                   9     Alice is lucky, 
                +++                         her code perfectly fits a square. 
                +++


++++++++        +++                   8     Though code length isn't enough for a square, 
                + +                         a small gap fixes it.
                +++


++++++          :~(                   6     No luck, code cannot be formatted.


Hello,          Hell                 12     Input may contain any ASCII characters, 
World!          o  ,                        but whitespaces in input should be ignored.
                W  o
                rld!


+++++ + +++++   +++++                22     Gap is not required to be a square, 
+++++ + +++++   +++++                       it can be a rectangle.
                +   +
                +++++
                +++++

+++ + +++       ++++++++             28     There exists another solution: 
+++ + +++       +      +                    6x6 square with 4x2 gap, 
+++ + +++       +      +                    but in Alice's opinion square gap 
+++ + +++       +      +                    makes code more readable.
                +      +
                +      +
                +      +
                ++++++++

Trudne testy

This must be    Thism                24     7x7 with 5x5 gap looks good,
5x5 with 1x1    ustbe                       but 5x5 with 1x1 gap is better,
gap.            5x 5w                       because gap area is smaller.
                ith1x
                1gap.

+++ +++ +++     :~(                  18     In case you tried 5x5 square
+++ +++ +++                                 with 7x1 gap ;)

Zasoby

Aby zaoszczędzić miejsce, możesz znaleźć przykładowy kod i dodatkowe przypadki testowe na tio.run

[Nowość] Możesz rzucić okiem na tabelę przyjętych rozwiązań dla wprowadzania do 100 znaków . Zmieniłem szerokość i wysokość, ponieważ wydaje się to bardziej intuicyjne.

Inspirowany przez: Kwadrat tekstu

Zmiany

  • Dodano 2 testy, naprawiono błąd w przykładowym kodzie.

  • Dodano tabelę rozwiązań do 100, dodano wyjaśnienie białych znaków.

Daniil Tutubalin
źródło
3
„Jeśli formatowanie jest niemożliwe, wyjdź płaczący emoji” - niepotrzebny puch, pozwalając każdemu wyjściu lepiej IMO.
Jonathan Allan
1
@JonathanAllan, jeszcze lepiej byłoby zagwarantować, że formatowanie jest zawsze możliwe. Boo-urny do sprawdzania poprawności danych wejściowych!
Kudłaty
1
@Jonathan Allan, wszelkie wyniki są zbyt szerokie i mogą być podatne na luki. Myślałem o pozwoleniu na użycie dowolnych wartości fałszowania, ale spowodowałoby to niespójność danych wyjściowych między różnymi językami. Zastanawiałem się również nad użyciem pustego ciągu, ale spowodowałoby to, że uruchamianie przypadków testowych byłoby mniej wizualne. Pomyślałem także o innych komunikatach, takich jak „Błąd”, ale postanowiłem, że będzie jeszcze krótszy, aby wspierać programistów Brainfuck na całym świecie.
Daniil Tutubalin
1
@Shaggy, to nie jest tylko sprawdzanie poprawności danych wejściowych. Stwierdzenie, że nie ma rozwiązania, jest ważną częścią układanki: musisz dowiedzieć się, kiedy przestać szukać.
Daniil Tutubalin
2
@DaniilTutubalin bardzo często zapewnia się, że zostaną tu podane tylko niektóre dane wejściowe. Zezwolenie na jakiekolwiek dane wyjściowe na takich „nieprawidłowych” danych wejściowych jest również powszechnym podejściem i pozwala uniknąć kodu, który nie ma nic wspólnego z rdzeniem wyzwania. Jeśli naprawdę potrzebujesz czegoś niezmiennego jako wyjścia w takich przypadkach, sugerowałbym sam wkład. Nie sugeruję jednak, żebyś to teraz zmienił ... to także bardzo miłe wyzwanie!
Jonathan Allan

Odpowiedzi:

5

C (gcc) , 354 bajty

h,i,j,k,l,m;g,v,w,d;f(char*s){for(i=l=0;s[i];l+=!isspace(s[i++]));d=g=l;for(i=0;i++<l;)if(h=i*i-l)for(j=0;j<i-++j;h>0&h%k<1&k<=m&m<i&m+~k&&m-k<g|m==k+g&(d-2*v)*(d-2*w)>h?w=(i-m)/2,v=j,g=m-k,d=i:j)k=i-2*j,m=h/k;else g=0,v=w=d=i;if(g-l)for(i=j=1;*s;j+=!i++,k=0,i%=d+1)for(putchar(i?v>=j|j>d-v|w>=i|i>d-w?k=1,*s:32:10);k;k*=isspace(*++s));else puts(":~(");}

Wypróbuj online!

attinat
źródło
Myślę, że tabulator to „biała spacja”, chociaż poprosiłem o wyjaśnienie, co dokładnie się liczy.
Jonathan Allan
Zaktualizowałem post. Można wymienić isspace(x)z x<33.
Daniil Tutubalin
349
ceilingcat
4

JavaScript (ES6),  284 ... 274  270 bajtów

Zaoszczędź 4 bajty dzięki @Shaggy

Zwraca tablicę ciągów.

s=>(s=s.replace(/\s/g,''),n=s.length,o=[':~('],W=d=g=(x,w=0,h=p=0)=>4*~-x>n?o:h>w?++w>x-2?g(-~x):g(x,w):g(x,w,h+1,o=n-x*x+w*h|(w^x|h^x)&!!(w|h)|w-h>d|w-h==d&w>W?o:[...Array(x)].map((_,Y,a)=>a.map((_,X)=>2*X>=x-w&2*X<x+w&2*Y>=x-h&2*Y<x+h?' ':s[p++]).join``,d=w-h,W=w)))``

Wypróbuj online!

Arnauld
źródło
Dobra robota! Chociaż spróbuj tego testu: This must be 5x5 with 1x1 gap.(24 znaki)
Daniil Tutubalin
1
@DaniilTutubalin Dlatego usunąłem swój początkowy post (i zasugerowałem taki przypadek testowy), ale teraz jest on obsługiwany poprawnie.
Arnauld
Nie może [\s\n]być po prostu \s?
Kudłaty
++w>x-2w++>=x-2w++>=x42 na przykład ). Ale \soszczędza 4 bajty. Dzięki. :)
Arnauld
4

Stax , 80 bajtów

ö╦Çc▀╕╡ëé╓]µiÖ9♪`W|╣▐↑╖D┘↕♫╗╔äƒ■úφ■U`ÿ⌠%é┴☼vAú)☺@ı◄¬¶¢(îÉ┼6⌠D~♀└lfæA.I@º╤∟òîü╦(

Uruchom i debuguj

Jak to działa?

  • Rozważ wszystkie kwadraty z prostokątnymi wycięciami.
  • Odfiltruj kształty programu, które nie mają właściwego rozmiaru.
  • Filtruj kształty programu, które nie mają pasującej parzystości.
  • Odfiltruj kształty programu, w których wycięcie jest zbyt duże dla kwadratu.
  • Jeśli nie zostaną znalezione, błąd wyjściowy i wyjście.
  • Znajdź kształt, który minimalizuje „prostokątność” wycięcia, a następnie według rozmiaru wycięcia.
  • Zastąp każdy znak w kształcie programu odpowiednim znakiem na wejściu programu.

Rozpakowane, niepolowane i skomentowane to wygląda tak.

                input e.g. "big socks"
L$j$            remove whitespace from input e.g. "bigsocks"
cr{~F           copy push each remaining character to input stack in reverse order
%c              get length L of flattened input and copy e.g. 8
^r3:$           create triples [a,b,c] in range 0..n e.g. [[0,0,0], [0,0,1], ... [8,8,8]]
{E*NsJ+n=f      filter triples: require a*a-b*c=L e.g. [[3,1,1], [4,1,8], ...]
{ET>f           filter triples: a>b and a>c e.g. [[3,1,1]]
{{2%m:u_0#+f    filter triples: a%2=b%2=c%2 or b*c=0 e.g. [[3,1,1]]
":~("s|c        if there are no triples, output ":~(" and terminate
{D:s_D:*\oh     sort by [abs(b-c),b*c]; keep the first e.g. [3,1,1]
X               store the chosen triple in the X register
E               explode onto stack e.g. 3, 1, 1
z)]*            using last two values, make a rectangle of zeroes e.g. 3, [[0]]
~               this will be the cutout, push it to the input stack
c'X*]*          make a square of "X" e.g. ["XXX", "XXX", "XXX"]
xEd-h           given the dimensions in x register, calculate the centered cutout coordinates
xEsd-h          e.g. ["XXX", "XXX", "XXX"], 1, 1
,||             embed the cutout grid at the specified coordinates e.g. ["XXX", "X X", "XXX"]
m'X{,]}R        for each line, regex replace "X" with a character from the input stack

Uruchom ten

rekurencyjny
źródło
Czy możesz również podać wersję bez rozpakowania?
Daniil Tutubalin
1
@DaniilTutubalin Dodałem wyjaśnienie.
rekurencyjny
Dziękuję Ci! Dobra robota!
Daniil Tutubalin
2

Węgiel drzewny , 120 bajtów

≔E⮌⪫⪪S ωιθ≔⁰ηF⊕Lθ¿⁼Lθ×ιι«≔ιη≔ιζ≔ιε»F⊘ιF⊕κF∧⁼Lθ⁻×ιι×⁻ι⊗⊕κ⁻ι⊗⊕λ∨¬η›⁻ζε⁻κλ«≔ιη≔⊕κζ≔⊕λε»¿η«UOη#JεζF›η⊗ζUO⁻η⊗ε⁻η⊗ζψUMKA⊟θ»:~(

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

≔E⮌⪫⪪S ωιθ

Usuń spacje z danych wejściowych, a następnie odwróć i podziel je na znaki, abyśmy mogli później łatwiej zapętlić znaki.

≔⁰η

Zacznij od rozmiaru zero, co oznacza, że ​​nie znaleziono (jeszcze) wyniku.

F⊕Lθ

Sprawdź wszystkie długości boczne do długości sznurka. (Dodanie podziału oczywiście przyspieszyłoby kod).

¿⁼Lθ×ιι«≔ιη≔ιζ≔ιε»

Jeśli wynik okaże się idealnym kwadratem, zapisz rozmiar kwadratu, a także ustaw go jako rozmiar ramki.

F⊘ιF⊕κ

Pętla nad możliwymi wysokościami i szerokościami granic (szerokość krawędzi nie jest większa niż wysokość granicy, dzięki czemu wysokość szczeliny nie jest większa niż szerokość szczeliny).

F∧⁼Lθ⁻×ιι×⁻ι⊗⊕κ⁻ι⊗⊕λ∨¬η›⁻ζε⁻κλ«≔ιη≔⊕κζ≔⊕λε»

Jeśli rozmiar obramowania jest pożądaną długością i nie mamy jeszcze rozwiązania lub nie jest on tak kwadratowy jak to rozwiązanie, zaktualizuj rozwiązanie przy użyciu tego rozmiaru kwadratu i obramowania.

¿η«

Jeśli mamy rozwiązanie ...

UOη#

Narysuj prostokąt o dowolnym charakterze o danym rozmiarze kwadratu.

JεζF›η⊗ζUO⁻η⊗ε⁻η⊗ζψ

Jeśli granica jest wystarczająco mała, aby pozostawić lukę, usuń ją. (Polecenie rysowania będzie rysować w górę i w lewo dla wartości ujemnych i wcale nie lubi wartości zerowych.)

UMKA⊟θ

Zamień wszystkie (pozostałe) znaki na znaki z wejścia.

»:~(

W przeciwnym razie wyjście :~(.

Neil
źródło
2

Galaretka , 91 85 bajtów

ÆDżU$<Ạa;ḂEɗʋƇṢƑƇ;€€
ḟ⁶ḟ⁷;©⁶L’²<¥Ðḟ²_ç;,`Wɗ¹?⁸ʋ€$Ẏạ/ÞḢµIH+""Rp"/ḟ@/ŒṬ€ĖP€Sị®Yµ“:~(”¹?

Wypróbuj online!

Łącze monadyczne, które przyjmuje ciąg wejściowy jako argument i zwraca ciąg znaków ze sformatowanym wyjściem lub :~(.

Nick Kennedy
źródło
1

Python 2, 287 281 279 bajtów

c=list("".join(input().split()))
l=len(c)
p=[]
for q in range(l*l):x=q%l;y=q/l;s=(l+x*y)**.5;p+=[(abs(x-y)/2,int(s),-x)]*(s%1==0)*(x<s-1>y>=s%2==x%2==y%2or x<1)
if p:d,s,x=min(p);b=(s+x)/2;Y=0;exec"c[b:b]=' '*-x*(b+d<=Y<s-b-d);print''.join(c[:s]);c=c[s:];Y+=1;"*s
else:print':~('

Wypróbuj online!

Korzysta z porównania listy leksykograficznej Pythona, używając tych samych wartości do wyboru rozwiązania i wydrukowania go. Jestem prawie pewien, że 10 4 2 bajtów wciąż można zgolić.

Wyjaśnienie

c=list("".join(input().split()))
l=len(c)
p=[]

Usuń białe znaki, dzieląc je białymi znakami i łącząc się z nimi "", a następnie przekonwertuj dane wejściowe na listę na później. Zainicjuj także ldługość aktualnego kodu i plistę prawidłowych możliwości.

for q in range(l*l):x=q%l;y=q/l;s=(l+x*y)**.5;

Pętla przez wszystkie możliwości wielkości szczelin od 0*0do l*l. Oblicz długość krawędzi kwadratu za pomocą lznaków kodowych i x*yspacji jako s.

p+=[(abs(x-y)/2,int(s),-x)]*(s%1==0)*(x<s-1>y>=s%2==x%2==y%2or x<1)

Sprawdź, czy spełnione są następujące warunki:

  • s % 1 == 0, tzn. powstałby idealny kwadrat
  • x < s-1 > y, To znaczy xi yco najwyżej s-2i zmieścić wewnątrz kwadratu
  • s % 2 == x % 2 == y % 2, tj. zarówno xiy dopasować parytetu krawędzi i może być wyśrodkowany
  • ale jeśli x < 1, tj. x == 0zignorujesz wszystko oprócz idealnego kwadratu

Jeśli warunki są zgodne, dodaj następujące elementy w krotce, paby znaleźć optymalny:

  • abs(x-y)/2; najpierw znajdź minimalną różnicę xi yuzyskaj jak najwięcej kwadratowych odstępów. Dzieje się tak zawsze, więc dzielimy przez 2.
  • int(s); następnie znajdź minimalną długość boku. Ponieważ sjest liczbą całkowitą i zwiększa się wraz z obszarem przerwy x*y, sortuje się według obszaru przerwy.
  • -x; następnie znajdź maksymalną szerokość, aby preferować odstępy poziome. Dzieje się tak po tym obszarze, ponieważ został opracowany, ale obszar jest taki sam x*yi y*xdziała.
if p:d,s,x=min(p);b=(s+x)/2;Y=0

Jeśli znaleźliśmy prawidłowe układy, znajdź optymalny, jak opisano powyżej. Oblicz granicę poziomą bi zainicjuj numer linii Yna 0.

exec"c[b:b]=' '*-x*(b+d<=Y<s-b-d);print''.join(c[:s]);c=c[s:];Y+=1;"*s

Jeśli numer linii Yznajduje się wewnątrz odstępu (pionowa ramka jest b+d, z dkrotką), dodaj wartość odstępów szerokości odstępu po poziomej granicy w c. (Zmiana cpolega na tym, że potrzebujemy listy). Następnie wydrukuj linię kwadratu i usuń ją c. Powtarzaj sczasy, zwiększając numer linii.

else:print':~('

Jeśli nie znaleziono żadnych układów, nie powiodło się.

PurkkaKoodari
źródło
Dobra robota! Niestety, nie działa dobrze z wejściem wieloliniowym. Wygląda również na to, że nie obsługuje prostokątnych szczelin (patrz test o długości 22).
Daniil Tutubalin
1
@DaniilTutubalin Musisz podać dane wejściowe jako ciąg znaków w języku Python, multilinia byłyby dosłownie "some\ntext"jako separatory. ( input()ocenia wiersz danych wejściowych jako kod Pythona). Jeśli nie jest to dopuszczalne, daj mi znać. Długość 22 również mi odpowiada.
PurkkaKoodari
ouch, przepraszam. Prawdopodobnie zrobiłem coś złego z danymi wejściowymi.
Daniil Tutubalin
1

Pyth , 99 98 bajtów

#JscQ)=QshKh|oaFtNSf!|%hT1&eT|t{%R2TgeStThT+L@+lJ*Fd2^UJ2
":~("Am/-Qd2tKW=W}~hZrG-QGJj*eKdcJ]H<~>J

Wypróbuj online!

Używa tego samego algorytmu, co moja odpowiedź w Pythonie, ale wiele szczegółów zostało znacznie zmienionych, aby były krótsze w Pyth.

Pyth pokazuje tutaj swój wiek, ponieważ nie był aktualizowany od wieków i używa tylko drukowalnych znaków ASCII (dla kodu, a nie danych), marnując dużo miejsca.

Co ciekawe, jeśli Pyth używałby tego samego rodzaju pakowania base-256 co Stax, ten program mógłby mieć ⌈98 log 256 95⌉ = 81 bajtów długości, tuż obok Stax (80 bajtów) i Galaretki (85 bajtów). Myślę, że to ładnie pokazuje, jak bliskie są golfowe języki nawet przy ich drastycznie różnych paradygmatach.

Objaśnienie (tylko nieco mniej nieczytelne niż kod)

#otacza wszystko, while True:co pomija komunikat i kończy działanie po błędzie.

JscQ) cwejście chmielu (Q ) w białych sznakach, łączy części razem i zapisuje wynik J.

^UJ2tworzy listę indeksów ( U) Ji przyjmuje swoją 2potęgę kartezjańską ( ^), co daje wszystkie pary[h,w] z 0<=h<len(J)i 0<=w<len(J).

+L@+lJ*Fd: dla wszystkich ( L) takich par ddodaje ( +) pierwiastek kwadratowy ( @2) z ( leng Jplus plus +) produktu (*F ) pary d) z lewej strony pary, tworząc triplet [side length, gap height, gap width].

f!|%hT1&eT|t{%R2TgeStThT: f ilter dla trojaczków Tgdzie

  • żaden z ( !|):
    • długość boku (hT ) modulo 1 ( %1) jest różna od zera
    • oba z ( &):
      • wysokość szczeliny (eT ) jest różna od zera
      • albo z (| ):
        • każda liczba w tryplecie ( R) modulo 2 ( %2), z duplikatami ( {) i pierwszym unikalnym (t usuniętymi ), jest niepusta
        • większa ( eS) wysokość szczeliny i szerokość szczeliny ( tT) jest grówna lub większa niż długość boku ( hT)

Ssortuje trojaczki leksykograficznie (według długości boku, a następnie według wysokości szczeliny). oaFtNnastępnie oociera trojaczki o absolute różnicę między wysokością i szerokością szczeliny (tN ).

W tym momencie, jeśli nie mamy prawidłowych rozwiązań, |ocenia swój drugi argument \n":~(", który drukuje i zwraca :~(. hprzyjmuje optymalne rozwiązanie (lub ":"jeśli nie ma) i zostaje zapisane K. Następnieh przyjmuje długość boku (lub ":"jeśli nie ma), srzutuje na liczbę całkowitą (lub kończy się niepowodzeniem i kończy pracę, jeśli nie ma) i jest zapisywany (= ) wQ .

Każda z ( m) [gap height, gap width]( tK) jest następnie odejmowana ( -) od długości boku ( Q), a wynik dzielony przez 2 ( /2 ). Wyniki są Aprzypisane do GiH .

Wreszcie wchodzimy w Wpętlę Hile.Zzaczyna się od 0 i każdą iterację zwiększamy, ale używamy starej wartości ( ~hZ, pomyśl Z++w C).

  • Jeśli ( W) stara wartość jest w ( {) range Gdo (długość boku - G) ( -QG), przypisz ( =) do J:c przeskocz Jw pozycji ( ]) Hi jo połówki o szerokości szczeliny eKrazy ( *) spację (d ). Jeśli wartość nie była w zakresie, po prostu wróć J. Jeśli ten wynik jest pusty, zatrzymaj pętlę.
  • Usuń ( >) pierwszyQ znaki z Ji przypisz ( ~) wynik do J. Ze starej wartości Jweź ( <) pierwsze Qznaki i wydrukuj je.

Wreszcie # pętla rozpoczyna się od nowa, bo błędy i zamknięcia cQ)z Qzawierającym numer jest nieprawidłowy.

PurkkaKoodari
źródło
Szczerze mówiąc, bardziej lubię kod do druku. Chociaż kod binarny zajmuje mniej miejsca, wygląda znacznie mniej apealicznie (wolałbym widzieć go jako zrzut szesnastkowy) i zwykle dokonuje się porównania między rozwiązaniami w tym samym języku. Tak więc krótsze zapakowane rozwiązanie Stax w porównaniu do innego zapakowanego rozwiązania Stax nadal będzie krótsze po rozpakowaniu obu. Pakowanie ma sens tylko dla ogólnej złożoności Kołmogorowa.
Daniil Tutubalin
@DaniilTutubalin Niezależnie od tego, jak zwykle dokonuje się porównania, nadal fajnie jest pokonać inny golfowy golf;)
PurkkaKoodari
1

05AB1E , 95 89 bajtów

… 
    мDg©Ý3ãʒćnsP-®Q}ʒć‹P}ʒÈËyß_~}Dg_i…:~(ëΣ¦DÆÄsP‚}н©¤_iнë¬Uć᤮Ås<иs;R`X*+šXnª£®θð×ýX}ô»

Kilka bajtów tu i tam na pewno można grać w golfa.

Pierwsze trzy kroki programu zostały zainspirowane odpowiedzią Stax @recursive , więc upewnij się, że go głosujesz!

Wypróbuj online lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie:

Krok 1: Usuń wszystkie białe spacje:

 
                   # Push string " \n\t"
    м              # And remove those from the (implicit) input-string

Krok 2: Utwórz wszystkie możliwe trojaczki [za,b,do], gdzie za jest wymiarem wynikowym za×za kwadrat i b×dojest wielkością luki. Robimy to, tworząc wszystkie możliwe trojaczki za pomocą liczb całkowitych z zakresu[0,za]. A następnie filtrujemy je tam, gdzie wszystkie poniższe elementy są zgodne z prawdą dla trypletu:

  • za2)-b×do=L., gdzie L. jest długością łańcucha
  • (za>b) i (za>do)
  • (za(mod2))=b(mod2))=do(mod2))) lub (mjan(za,b)0)

Na przykład: L.=28spowoduje trojaczki [[6,2,4],[6,4,2],[8,6,6]].

Dg                 # Get the length of this string (without popping by duplicating first)
  ©                # Store this length in variable `®` (without popping)
   Ý               # Create a list in the range [0,®]
    3ã             # Create all possible triplets by repeating the cartesian product 3 times
ʒ                  # Filter these triplets by:
 ć                 #  Extract head; pop and push remainder-list and head to the stack
  n                #  Square the head
   sP-             #  Take the product of the remainder, and subtract it from the squared head
      ®Q           #  And check if it's equal to the string length in variable `®`
                 # Filter the remaining triplets further by:
  ć‹P              #  Where the first integer is larger than the other two
      }          # And filter it a third time by:
  ÈË               #  Where all three are either odd or even
       ~           #  Or
    yß_            #  It does not contain any 0s

Krok 3: Sprawdź, czy nadal mamy jakieś trojaczki. Jeśli nie, wyjdź":~(" ; jeśli tak, określ, którego użyć, sortując i pozostawiając tylko pierwszy. Robimy to, sortując krotki(zabs(b-do),b×do).

Na przykład: trojaczki [[6,2,4],[6,4,2],[8,6,6]]zostaną posortowane [[8,6,6],[6,2,4],[6,4,2]], po czym [8,6,6]pozostanie tylko .

Dg_i               # If this completely filtered list is now empty:
    …:~(           #  Push string ":~("
ë                  # Else:
 Σ                 #  Sort the triplets by:
  ¦                #   Remove the first character
   DÆÄ             #   Get the absolute difference between the remaining two integers
   sP             #   And pair it with the product of the remaining two integers
                 #  After we're done sorting: only leave the first triplet

Krok 4: Utwórz listę, w jaki sposób powinniśmy podzielić ciąg, aby wstawić spacje. Odbywa się to w następujący sposób:

Dany [za,b,do], utwórz listę z:

  • Jako pierwszy przedmiot: za-b2)×za+za-do2)
  • W środku b-1 przedmiotów: za-do
  • Jako ostatni przedmiot: za2)

Na przykład: triplet [7,3,5]spowoduje wyświetlenie listy [15,2,2,35].

©                  #  Store this triplet in variable `®` (without popping)
 ¤_i               #  If the last value is 0 (which means the string is a square without gap):
    н              #   Simply keep the first value of the triplet
   ë               #  Else:
    ¬U             #   Store the first value in variable `X` (without popping)
      ć            #   Extract the first value; pop and push remainder-list and head to the stack
       α           #   Get the absolute difference of this head with the other two values
        ¤          #   Push the last value (without popping the pair itself)
         ®Ås     #   And repeat it the middle element or `®` minus 1 amount of times
       s           #   Swap to get the difference pair again
        ;          #   Halve both values
         R`        #   Push them reversed to the stack
           X*      #   Multiple the first value by `X`
             +     #   And then add it to the second value
              š    #   Prepend this in front of the repeated list
               Xnª #   And also append the square of `X`

Krok 5: I w końcu podzieliliśmy ciąg znaków na podstawie tej listy, połączmy go z powrotem razem z do ilość spacji, podziel ją na części wielkości doi dołącz do nich razem przez nowe linie. Na przykład:

String "Alongtesttoseeifitworksasintended."podzielone według listy [15,2,2,35]spowoduje: ["Alongtesttoseei","fi","tw","orksasintended."]. Następnie dołączado=5ilość miejsc do "Alongtesttoseei fi tw orksasintended.". A następnie podzielony na części wielkościza=7do tego: ["Alongte","sttosee","i f","i t","w o","rksasin","tended."]. Do których następnie dołączane są znaki nowej linii.

    £              #   Then split the string into parts based on this list
     ®θð×          #   Push a string consisting of the last value of `®` amount of spaces
         ý         #   Join the list of substrings by this
          X        #   Push variable `X`
                 #  After the if-else: split the string into parts of that size
     »             #  And then join these by newlines
                   # (after which the top of the stack is output implicitly as result)
Kevin Cruijssen
źródło