Utwórz siatkę jak najbliżej kwadratu, jak to możliwe

10

Utwórz funkcję lub program, który ustawi siatkę jak najbliżej kwadratu, jak to możliwe

  • Jako dane wejściowe otrzymasz liczbę całkowitą N , liczby całkowite (1,2,3,25 itd.)
  • Wyjściem musi być idealna prostokątna siatka N liter możliwie najbliżej kwadratu
  • Kwadrat (wannabe) musi składać się z jednej z liter O lub X określonych przez użytkownika

Punkty :

  • Zakodowane na stałe tylko dla O lub X: +1
  • Param (0/1, prawda / fałsz, coś podobnego) do obracania wyjścia (jak przy 5 lub 8): -10
  • Zaprojektuj kwadrat (użyj zarówno O, jak i X w pewnym wzorze): -5

Wzór uważa się za prawidłowy, jeśli zawiera oba typy znaków (gdzie oś x / y> = 3), a wzór pozostaje taki sam, gdy jest odwrócony w poziomie lub w pionie (dozwolona jest wymiana X z Os)

Przykłady

INPUT: 4         INPUT: 5       INPUT: 8              INPUT: 9
OO               OOOOO          XXXX                  XOX
OO                              XXXX                  OXO  
                                or rotated 90deg      XOX

Przykłady, które są niedozwolone (inny wiersz lub kolumna o tej samej długości)

BAD RESULT: 5a        BAD RESULT: 5b      BAD RESULT: 8
OOO                   OO                  OOO
OO                    OO                  OOO
                      O                   OO

Jeśli to możliwe, podaj przykład online.

Martijn
źródło
Czy funkcja jest wystarczająca, czy chcesz mieć pełny program?
John Dvorak,
„Zaprojektuj kwadrat ... w przypadku 9 zmień środek” - w jakich dokładnie okolicznościach wzór nie jest szachownicą? Czy możesz podać przykład?
John Dvorak,
ponowna edycja: czy poprawnie przeczytałem, że "xo"[i]zamiast tego dostaję trzy punkty i? To nie wydaje się tego warte. Ogólnie rzecz biorąc, wszystkie twoje nagrody wydają się trochę niskie.
John Dvorak,
„jakiś wzór” jest trochę niejasny. Czy to się liczy, jeśli zamienię pierwsze „x” na „o”?
John Dvorak,
Dobre pytanie. Jedynym interesującym bonusem / karą jest rotacja. Osobiście trzymałbym się jednej, zakodowanej postaci (tj. Ustawiłbym karę jako domyślną) i wyeliminowałbym wszystkie bonusy / kary oprócz pewnej rotacyjnej. Nie jest zbyt dobrym pomysłem mieć zbyt wiele bonusów lub kar. Ważne jest, aby jasno określić główny problem.
Level River St

Odpowiedzi:

6

CJam, 16 (31–10–5)

To trwa dwie liczby całkowite są wprowadzane, najpierw samopoczucie 0lub 1na drugim kierunku i jest liczbą Olub Xw sieci.

Drukuje alternatywne Oi X.

:X"OX"*X<\Xmqi){(_X\%}g_X\/?/N*

To jest tylko funkcja funkcji, aby ją wypróbować dodaj l~przed kodem, np .:

l~:X"OX"*X<\Xmqi){(_X\%}g_X\/?/N*

i dać wkład jak

0 10

aby uzyskać wynik jak

OXOXO
XOXOX

lub wejście jak

1 10

dla

OX
OX
OX
OX
OX

Wypróbuj online tutaj


Jak to działa:

l~                                 "Put the two input integers to stack";
  :X                               "Assign the number of cells to X";
    "OX"*                          "Take string "OX" and repeat it X times";
         X<                        "Slice it to take only first X characters";
           \                       "Swap top two stack elements, now string is at bottom";
            Xmqi)                  "Take square root of X, ceil it and put on stack";
                 {(_X\%}g          "Keep decrementing until it is perfectly divisible by X";
                         _X\/      "Copy it, divide X by that and put it on stack";
                             ?     "Based on first input integer, take either of numbers";
                              /    "Divide the XOXO string that many times";
                               N*  "Join the string parts with a new line";

Przykładowy przebieg:

l~ed:X"OX"*edX<ed\edXmqi)ed{(_X\%}ged_edXed\ed/ed?ed/edN*ed

#INPUT:
1 10

#OUTPUT:
Stack: [1 10]

Stack: [1 "OXOXOXOXOXOXOXOXOXOX"]

Stack: [1 "OXOXOXOXOX"]

Stack: ["OXOXOXOXOX" 1]

Stack: ["OXOXOXOXOX" 1 4]

Stack: ["OXOXOXOXOX" 1 2]

Stack: ["OXOXOXOXOX" 1 2 2]

Stack: ["OXOXOXOXOX" 1 2 2 10]

Stack: ["OXOXOXOXOX" 1 2 10 2]

Stack: ["OXOXOXOXOX" 1 2 5]

Stack: ["OXOXOXOXOX" 2]

Stack: [["OX" "OX" "OX" "OX" "OX"]]

Stack: ["OX
OX
OX
OX
OX"]

OX
OX
OX
OX
OX
Optymalizator
źródło
3

APL (36-5-10 = 21)

{'OX'⍴⍨⍺⌽⊃∆/⍨⍵=×/¨∆←∆[⍋|-/¨∆←,⍳2/⍵]}

Lewy argument to rotacja, prawy argument to rozmiar. Używa również prostego wzorca (po prostu zamienia „X” i „O”).

      0{'OX'⍴⍨⍺⌽⊃∆/⍨⍵=×/¨∆←∆[⍋|-/¨∆←,⍳2/⍵]}¨4 5 8 9
 OX  OXOXO  OXOX  OXO 
 OX         OXOX  XOX 
                  OXO 
      1{'OX'⍴⍨⍺⌽⊃∆/⍨⍵=×/¨∆←∆[⍋|-/¨∆←,⍳2/⍵]}¨4 5 8 9
 OX  O  OX  OXO 
 OX  X  OX  XOX 
     O  OX  OXO 
     X  OX      
     O       

Wyjaśnienie:

  • ∆←,⍳2/⍵: wygeneruj wszystkie możliwe pary liczb od 1do i zapisz w .
  • ∆←∆[⍋|-/¨∆... ]: sortuj rosnąco według absolutnej różnicy dwóch liczb w każdej parze i zapisz wynik z powrotem .
  • ⊃∆/⍨⍵=×/¨∆: dla każdej pary pomnóż liczby razem. Wybierz tylko te pary, które się mnożą , i weź pierwszą pasującą (która jest „najbardziej kwadratowa” ze względu na sortowanie).
  • ⍺⌽: obróć listę długości (która ma 2 elementy) o .
  • 'OX'⍴⍨: utwórz macierz tego rozmiaru i wypełnij ją naprzemiennie Oi X.
marinus
źródło
2

Haskell, 59 znaków

r=replicate
f n=[r x$r y '0'|x<-[1..n],y<-[1..x],x*y==n]!!0
John Dvorak
źródło
2

CJam, 25 22 21 (31–10)

To jest ciało funkcyjne. Jeśli chcesz mieć pełny program, dodaj ririgo z przodu. Jeśli chcesz użyć go jako bloku kodu, otocz go {}. Przetestuj na cjam.aditsu.net .

Bierze dane wejściowe jako dwa argumenty całkowite: przełącznik określający, czy prostokąt jest pionowy (dowolna wartość niezerowa) czy poziomy (zero), oraz liczbę Os do użycia.

:Xmqi){(_X\%}g_X\/@{\}{}?'O*N+*

Wyjaśnienie

:X "Assign the top item on the stack (the second input) to variable X";
mq "Take its square root";
i  "Convert to integer (round)";
)  "Increment it";

{  "Start code block";
  (  "Decrement";
  _X "Duplicate top item on stack; push X to the stack";
  \% "Swap top 2 items and take division remainder";
}g "Loop until top item on stack is 0; pop condition after checking it";

_X "Duplicate top item on stack; push X to the stack";
\/ "Swap top 2 items and divide";

"OMIT THIS BIT TO GET A 25-CHAR FUNCTION WITHOUT THE 10PT BONUS";
 @  "Rotate top 3 items on stack";
 {\}"Code block 1: swap top two items";
 {} "Code block 2: do nothing";
 ?  "If top item of stack is 0, run code block 1, otherwise run code block 2";

'O "Push the character O to the stack";
*  "Repeat it N times, where N is the second item from the top of the stack (O is first)";
N+ "Push a new line and concatenate it with the string on the top of the stack";
*  "Repeat the string N times";

źródło
1
Zmniejszenie powinno być
znacznie
1
Kto przegłosował? Dlaczego?
2
Mogę tylko zgadywać, że ktoś nie uważa CJam za prawdziwy język
John Dvorak
Twoje wyjaśnienie jest trochę złamane. Czy obecnie edytujesz?
John Dvorak,
@JanDvorak Tak, byłem w połowie edycji i przypadkowo nacisnąłem Tab i Enter. Teraz jest naprawione.
2

JavaScript (E6) 84 (83 + 1) lub 101 (116-10-5)

Wzór + obrót (parametr f, 0 lub 1) - bonus 15

F=(n,f)=>{
  for(r=x=0;y=n/++x|0,x<=y;)x*y-n?0:z=f?x:y;
  for(o='';n;)o+=(n--%z?'':(r^=1,c='\n'))+'OX'[r^(c^=1)];
  alert(o)
}

Bez wzoru, bez rotacji - kara 1

F=n=>{
  for(x=0;y=n/++x|0,x<=y;)x*y-n?0:z=y;
  alert(('O'.repeat(z)+'\n').repeat(n/z));
}

Testuj w konsoli FireFox / FireBug

F(30,0)

OXOXOX
XOXOXO
OXOXOX
XOXOXO
OXOXOX

F(30,1)

OXOXO
XOXOX
OXOXO
XOXOX
OXOXO
XOXOX
edc65
źródło
2

Python, 79 75 (bez bonusów)

Bonusy wydają się trudne, więc tutaj jest całkiem prosta funkcja Pythona:

def f(N):c=max(x*((x*x<=N)>N%x)for x in range(1,N+1));print(N/c*'O'+'\n')*c
Emil
źródło
Przykład online dla zainteresowanych: repl.it/Zq9
Martijn
1
Czy zmieniłeś to po testach? Próbowałem tego i to nie działa, na przykład f(8)dał mi jedną kolumnę 8 Os, co jest niepoprawne.
marinus
@marinus: Testowałem, ale prawdopodobnie skopiowałem niewłaściwą wersję. Było miejsce, w >którym powinno być <. Teraz jest naprawione. Dzięki za notatkę!
Emil
1

Ruby, 74

f=->n{w=(1..n).min_by{|z|n%z>0?n:(n/z-n/(n/z))**2};$><<("X"*w+"\n")*(n/w)}

Wyjaśnienie

  • Dane wejściowe są traktowane jako argumenty do lambda. Oczekuje Integer.
  • Sprawdź, czy n(wejście) jest podzielne przez każdą liczbę całkowitą od 1 do n.
    • Jeśli tak, oblicz różnicę między długością a szerokością.
    • Jeśli nie jest, zwróć dużą liczbę ( n).
  • Weź najmniejszą różnicę długości i szerokości, aby najlepiej przypominała kwadrat.
  • Użyj (zbyt zwięzłej) String#*metody, aby „narysować” kwadrat.
Britishtea
źródło
Dlaczego zostałem zagłosowany? Czy moja odpowiedź zawiera błąd?
britishtea
Masz literówkę. Ostatnim słowem powinno być „kwadrat”, a masz „sqaure”. (Nie jestem zwycięzcą, wskazuję ten błąd).
Ismael Miguel
1

APL (Dyalog Unicode) , 30-15 = 15 bajtów SBCS

Anonimowy przyrostek lambda. Przyjmuje N jako prawy argument, a param jako lewy argument. Prostokąty będą miały paski X i O lub będą w szachownicę.

{⍉⍣⍺⍴∘'XO'⊃∘c⌈.5×≢c←⍸⍵=∘.×⍨⍳⍵}

Wypróbuj online!

{} „Dfn”; is left argument (param), is right argument ( N ):

⍳⍵d ndices 1… N

∘.×⍨ tabliczka mnożenia tego

⍵= maska, w której N jest równe

Wskaźniki prawdziwych wartości w masce

c← Przechowywać że c(na c andidates)

 zliczyć kandydatów

.5× połowa pomnożona przez to

 sufit (zaokrąglony w górę)

⊃∘c wybierz ten element z c

⍴∘'XO' użyj tego do cyklicznego przekształcania „XO”

⍉⍣⍺ transponuj, jeśli param

Adám
źródło
1

05AB1E (starsze) , wynik: 7 (22 bajtów - 15 premii)

„OXI∍¹tï[D¹sÖ#<}äIiø}»

Wypróbuj online lub sprawdź więcej przypadków testowych .

NNajpierw pobiera dane wejściowe , a następnie wartość logiczną ( 0/ 1), czy powinna się ona obracać, czy nie.

Używa starszej wersji 05AB1E w Pythonie, ponieważ zip z listą ciągów domyślnie spłaszcza i łączy znaki, w przeciwieństwie do nowszej wersji 05AB1E przepisującej Elixir.

Wyjaśnienie:

OX         # Push string "OX"
   I       # Extend it to a size equal to the first input
            #  i.e. 9 → "OXOXOXOXO"
            #  i.e. 10 → "OXOXOXOXOX"
¹t          # Take the first input again, and square-root it
            #  i.e. 9 → 3.0
            #  i.e. 10 → 3.1622776601683795
  ï         # Then cast it to an integer, removing any decimal digits
            #  i.e. 3.0 → 3
            #  i.e. 3.1622776601683795 → 3
   [        # Start an infinite loop:
    D       #  Duplicate the integer
     ¹sÖ    #  Check if the first input is evenly divisible by that integer
            #   i.e. 9 and 3 → 1 (truthy)
            #   i.e. 10 and 3 → 0 (falsey)
        #   #  And if it is: stop the infinite loop
    <       #  If not: decrease the integer by 1
            #   i.e. 3 → 2
   }        # After the infinite loop:
ä           # Divide the string into that amount of equal sized parts
            #  i.e. "OXOXOXOXO" and 3 → ["OXO","XOX","OXO"]
            #  i.e. "OXOXOXOXOX" and 2 → ["OXOXO","XOXOX"]
 Ii }       # If the second input is truthy:
   ø        #  Zip/transpose; swapping rows/columns of the strings
            #   i.e. ["OXOXO","XOXOX"] → ["OX","XO","OX","XO","OX"]
»           # And finally join the strings in the array by newlines
            #  i.e. ["OXO","XOX","OXO"] → "OXO\nXOX\nOXO"
            #  i.e. ["OX","XO","OX","XO","OX"] → "OX\nXO\nOX\nXO\nOX"
            # (and output the result implicitly)
Kevin Cruijssen
źródło
0

GolfScript 26 (41–10–5)

:x),1>{x\%!},.,2/=.x\/@{\}*'X'*n+*1>'O'\+

Oczekuje, że na stosie znajdą się dwa parametry:

  • 0dla normalnego lub 1transponowanego
  • nwartość

Wzór jest taki, że tablica jest pełna Xs, a lewy górny róg to O. Nie trzeba dodawać, że ten wzór zachowuje się podczas transpozycji planszy.

Demo: zwykłe , transponowane

Cristian Lupascu
źródło
0

Mathematica, 71 znaków

f@n_:=#<>"\n"&/@Array["O"&,{#,n/#}&[#[[⌊Length@#/2⌋]]&@Divisors@n]]<>""
alephalpha
źródło
0

Petit Computer BASIC, 72 bajty

INPUT N,S$FOR I=1TO SQR(N)IF N%I<1THEN M=I
NEXT
?(S$*M+" "*(32-M))*(N/M)
12Me21
źródło
0

J , 32 bajty - 15 = 17 bajtów

'XO'$~[|.](%,])i.@]{~0 i:~i.@]|]

Wypróbuj online!

Obrót jest kontrolowany przez flagę 0/1 wziętą jako lewy argument

Jonasz
źródło
0

Siatkówka 0.8.2 , 66 bajtów + 1 bajt kary = 67

.+
$*X
((^|\3)(X(?(3)\3)))+(\3)*$
$3 $3$#4$*X
X(?=X* (X+))| X+
$1¶

Wypróbuj online! Wyjaśnienie:

.+
$*X

Konwertuj dane wejściowe na ciąg Xs.

((^|\3)(X(?(3)\3)))+(\3)*$

Pierwszy przebieg przechwytywania zewnętrznego jest zgodny z początkiem ciągu, a przy kolejnych przejściach dopasowywana jest poprzednia wartość przechwytywania wewnętrznego. Wewnętrzne przechwytywanie jest następnie zwiększane i dopasowywane. Rezultatem tego jest to, że ilość łańcucha zużytego przez przechwytywanie zewnętrzne jest kwadratem przechwytywania wewnętrznego, a zatem nie może przekraczać pierwiastka kwadratowego wejścia. Tymczasem kolejne powtórzenie zapewnia, że ​​przechwytywanie wewnętrzne jest czynnikiem długości łańcucha.

$3 $3$#4$*X

Zapisz wykryty czynnik i oblicz drugi dzielnik, dodając liczbę kolejnych powtórzeń.

X(?=X* (X+))| X+
$1¶

Zmień układ czynników na prostokąt.

Neil
źródło
0

Węgiel drzewny , 33 bajty - 10-5 = 18

Nθ≔⌊Φ⊕θ¬∨‹×ιιθ﹪θιηE÷θη⭆η§XO⁺ιλ¿N⟲

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

Nθ

Wejście N.

≔⌊Φ⊕θ¬∨‹×ιιθ﹪θιη

Weź zakres 0... Nzachowaj tylko liczby, których kwadraty są nie mniejsze niż Ni podziel N, i weź minimum tych liczb.

E÷θη⭆η§XO⁺ιλ

Użyj odkrytego współczynnika, aby wygenerować prostokąt o odpowiedniej szerokości i wysokości za pomocą wzoru szachownicy. (Powinno to dotyczyć UOη÷θηXO¶OXoszczędności 1-bajtowej, ale w tej chwili jest to problem.)

¿N⟲

Jeśli drugie wejście jest niezerowe, obróć wyjście. (Jeśli wymaganie drugiego wejścia jest 0lub 2jest akceptowalne, może to oznaczać ⟲Noszczędność 1 bajtu).

Neil
źródło