Uczysz klasę uczniów z interesującymi preferencjami dotyczącymi rozmieszczenia ich krzeseł. Istnieją 3 bardzo szczegółowe wymagania dotyczące rozmieszczenia krzeseł:
Najczęściej są ułożone w prostokąt, nawet jeśli oznacza to, że niektóre krzesła są puste.
Musi być jak najmniej pustych krzeseł.
Muszą być możliwie „kwadratowe”. Kwadratowość zależy od odległości między szerokością a wysokością prostokąta, im niższa, tym lepiej. Na przykład prostokąt, który
4x7
ma kwadratowość 3.
Mówiąc ściślej, „wynikiem” aranżacji jest odległość między szerokością a wysokością plus liczba krzeseł, które mogłyby zostać puste.
Weźmy przykład. Powiedzmy, że masz 13 uczniów. Krzesła można ustawić w dowolny z następujących sposobów:
1x13
2x7
3x5
4x4
1x13
nie jest bardzo kwadratowy. W rzeczywistości 1 i 13 dzieli się na 12, więc dajemy temu układowi 12 punktów. Ma również 0 pustych krzeseł, więc dodajemy 0 punktów, co daje wynikowi 12 punktów. Niezbyt dobrze.
2x7
jest z pewnością lepszy. 2 i 7 są tylko 5 od siebie, więc dajemy temu układowi 5 punktów. Jeśli jednak faktycznie ustawisz 2 rzędy po siedem krzeseł, zajmie to 14 krzeseł, co oznacza, że jedno krzesło będzie puste. Dodajemy więc jeden punkt, co daje temu układowi wynik 6.
Możemy też zrobić 3x5
. 3 i 5 to 2 osobno, więc +2 punkty. Zajmuje 15 krzeseł, co oznacza, że mielibyśmy dwa dodatkowe krzesła, więc kolejne +2 punkty za wynik 4.
Ostatnia opcja, 4x4
. 4 i 4 są od siebie równe 0, więc dajemy to +0 punktów. 4x4 zajmuje 16 krzeseł, więc 3 krzesła są puste, co daje łączny wynik 3. To optymalne rozwiązanie.
W przypadku remisu optymalnym rozwiązaniem jest rozwiązanie z mniej pustymi krzesłami.
Wyzwanie
Musisz napisać program lub funkcję, która przyjmuje liczbę całkowitą i wyświetla optymalne ustawienie krzeseł dla tej liczby uczniów. IO może mieć dowolny rozsądny format. Oto przykładowe wyniki dla dowolnej liczby uczniów od 1 do 100:
1: (1, 1)
2: (1, 2)
3: (2, 2)
4: (2, 2)
5: (2, 3)
6: (2, 3)
7: (3, 3)
8: (3, 3)
9: (3, 3)
10: (2, 5)
11: (3, 4)
12: (3, 4)
13: (4, 4)
14: (4, 4)
15: (4, 4)
16: (4, 4)
17: (3, 6)
18: (3, 6)
19: (4, 5)
20: (4, 5)
21: (3, 7)
22: (5, 5)
23: (5, 5)
24: (5, 5)
25: (5, 5)
26: (4, 7)
27: (4, 7)
28: (4, 7)
29: (5, 6)
30: (5, 6)
31: (4, 8)
32: (4, 8)
33: (6, 6)
34: (6, 6)
35: (6, 6)
36: (6, 6)
37: (5, 8)
38: (5, 8)
39: (5, 8)
40: (5, 8)
41: (6, 7)
42: (6, 7)
43: (5, 9)
44: (5, 9)
45: (5, 9)
46: (7, 7)
47: (7, 7)
48: (7, 7)
49: (7, 7)
50: (5, 10)
51: (6, 9)
52: (6, 9)
53: (6, 9)
54: (6, 9)
55: (7, 8)
56: (7, 8)
57: (6, 10)
58: (6, 10)
59: (6, 10)
60: (6, 10)
61: (8, 8)
62: (8, 8)
63: (8, 8)
64: (8, 8)
65: (6, 11)
66: (6, 11)
67: (7, 10)
68: (7, 10)
69: (7, 10)
70: (7, 10)
71: (8, 9)
72: (8, 9)
73: (7, 11)
74: (7, 11)
75: (7, 11)
76: (7, 11)
77: (7, 11)
78: (9, 9)
79: (9, 9)
80: (9, 9)
81: (9, 9)
82: (7, 12)
83: (7, 12)
84: (7, 12)
85: (8, 11)
86: (8, 11)
87: (8, 11)
88: (8, 11)
89: (9, 10)
90: (9, 10)
91: (7, 13)
92: (8, 12)
93: (8, 12)
94: (8, 12)
95: (8, 12)
96: (8, 12)
97: (10, 10)
98: (10, 10)
99: (10, 10)
100: (10, 10)
Jak zwykle jest to gra w golfa, więc obowiązują standardowe luki, a zwycięzca jest najkrótszą odpowiedzią w bajtach.
Odpowiedzi:
Galaretka ,
161514 bajtówWypróbuj online! lub zweryfikuj wszystkie przypadki testowe .
Jak to działa
źródło
Python 2, 68 bajtów
Odpowiednik bardziej „oczywistego”:
źródło
range(-n,0)
, tak jak ja w mojej odpowiedzi . Zestaw testowy.Haskell, 65 bajtów
Przykład użycia:
map f [1..5]
->[(1,1),(1,2),(2,2),(2,2),(2,3)]
.Przechodzi przez zewnętrzną pętlę
a
od1
dox
(x -> liczba uczniów) i wewnętrzną pętlęb
od1
doa
. Przechowuje wszystko(b,a)
gdziea*b>=x
i buduje pary((arrangement points,seats left), (b,a))
zgodnie z porządkiem leksykograficznym, musimy znaleźć minimum. Uwaga:a
zawsze jest większa niżb
, więc nie potrzebujemyabs
kwadratowości. Nie trzeba odejmować wynikux
od „wolnych miejsc”, ponieważ liczy się tylko kolejność względna. Na koniec usuwamy parę wyników za pomocąsnd
.źródło
a*b
(liczba wolnych miejsc) to remis, jeśli główny wynik jest równy. Przykładn=43
A)a=7, b=7
, Wynik:(49,49)
b)a=9, b=5
, Wynik:(49,45)
. Główny wynik jest równy, decyduje remis, b) wygrywa.a*b
, same liczby,(b,a)
które muszę nosić przy sobie, działają jak remis i dają takie same wyniki dla (przynajmniej)n=1..300
. Produkt jest mały, jeśli jeden z czynników (tutajb
) jest mały. Ale dopóki nie mam formalnego dowodu, nie chcę tego faktu używać. Zobaczmy, czy go znajdę.Rubinowy, 64 bajty
Lambada, która przyjmuje liczbę ludzi jako argument i zwraca tablicę o szerokości i wysokości optymalnego rozwiązania.
źródło
w*h
jako drugiego elementu w tablicy? Nie wydaje mi się, żeby szczególnie to zmieniało, kiedy dzwonisz,min
ponieważ minimalizujesz wynik, czyli pierwszy element.In case of a tie, the optimal solution is the one with less empty chairs
MATL , 18 bajtów
Wypróbuj online!
Wyjaśnienie
źródło
JavaScript, 98 bajtów
Mój pierwszy golf golfowy, więc i tak publikuję!
Początkowo mój
o
był pustym przedmiotem i sprawdziłem, czyo.a
był pusty, więc był to szczególny przypadek w pierwszej rundzie. Ale znalazłem sztuczkę 1/0 w odpowiedzi edc65, aby zainicjować zmienną na Infinity.źródło
Pyth,
242221 bajtówEdycja : w kluczu sortującym zdaję sobie sprawę, że nie ma potrzeby znajdowania liczby pustych krzeseł. Odpowiada to całkowitej liczbie krzeseł. To zaoszczędziło mi 2 bajty.
Wypróbuj online!
źródło
Matlab
(174) (146)121sztuczka 1: dodałem kwotę
1-1/length*width
jako remissztuczka 2: obliczyłem
number_students/length
pułap dla szerokości prostokąta,górna granica to kwadrat, ale też sufitJestem pewien, że można dalej grać w golfa ...
Spróbuj
Edycja: odniesienie do uwag @StewieGriffin.
Edycja 2:
1
in
są stałymi, których nie trzeba dodawać do ogólnego wyniku.Edycja 3: test wydajności.
źródło
unique
Python 2, 64 bajty
Jest to połączenie odpowiedzi Pythona @ Lynn (skąd wziąłem
max(...)[1:]
lewę) i algorytmu z mojej odpowiedzi Julii (która pozwala na nieco krótszą implementację).Przetestuj na Ideone .
źródło
Julia,
6159555352 bajtyWypróbuj online!
Jak to działa
Kod jest równoważny z następującą wersją bez golfa, w której
cld
podział sufitu.Aby znaleźć optymalne ustawienie, wystarczy wyraźnie zbadać pary [i, j] , gdzie 1 ≤ i ≤ n oraz j = ⌈n / i⌉ .
Wynik takiego układu wynosi | j - i | + (ij - n) , gdzie drugim summand jest liczba pustych krzeseł. Zamiast faktycznych wyników, możemy porównać wyniki powiększone o stałą, taką jak ij + | j - i | + 1 .
Wystarczy wziąć pod uwagę pary [i, j] gdzie i ≤ j, ponieważ ustalenia [i, j] i [j, i] są jednakowo ważne. Mamy do czynienia z ściśle malejącymi parami, ustawiając zamiast tego j = max (⌈n / i⌉, i) , co zapewnia, że j ≥ i da wynik nieoptymalny, jeśli ⌈n / i⌉ <i .
Ponieważ j - i ≥ 0 , mamy ij + | j - i | + 1 = ij + j - i + 1 = (i + 1) × (j - 1) , które można obliczyć w mniejszej liczbie bajtów kodu.
Na koniec
indmin
/indmax
podaje wskaźnik m (a zatem wartość i ) optymalnego układu, który wynosi m o ⌈n / m⌉ . Więzy są zrywane przy pierwszym wystąpieniu, które odpowiada najniższej wartości i , a zatem najwyższej wartości j - i, a tym samym najniższej wartości ij - n (puste krzesła).źródło
JavaScript (ES6) 74
78Edytować zachowując wynik temp jako tablicę zamiast 2 zmiennych, zapożyczoną z odpowiedzi Thiht
Mniej golfa
Test
źródło
PHP, 129 bajtów
Nie golfowany:
źródło
PHP, 104 bajty
Algorytm rozwiązujący ten problem jest prosty i prawdopodobnie jest używany przez inne odpowiedzi w językach podobnych do PHP (JavaScript, fe):
n
jest wystarczająco duży (gdzien
jest wartość wejściowa); wynik aranżacji obliczony przy pierwszej iteracji (1, n
) wynosi(n-1)+0
;1
in
; obliczyć minimalną wysokość jakoceil(n/width)
, obliczyć wynik aranżacji za pomocą wzoru podanego w pytaniu (tjabs(width - height) + (width * height - n)
); jeśli wynik jest lepszy niż poprzedni najlepszy wynik, pamiętaj o szerokości, wysokości i nowym najlepszym wyniku; w przypadku powiązań użyj wartościwidth * height - n
dla bieżącego uzgodnienia i poprzedniego najlepszego uzgodnienia w celu wykrycia nowego najlepszego uzgodnienia;Po grze w golfa ten algorytm tworzy coś takiego (zawinięte tutaj dla czytelności):
Używa 137 bajtów (po umieszczeniu w jednym wierszu) i dalekie jest od 104 bajtów podanych w tytule. Kod można prawdopodobnie skrócić o kolejne 2-3 bajty, ale dużym źródłem usprawnień jest gdzie indziej: w szczegółach algorytmu.
Zmieniony algorytm:
Istnieje kilka miejsc, w których algorytm można ulepszyć, usuwając niepotrzebny kod.
1
do$n
; dla prędkości, szerokość ($i
) musi się powtarzać między1
afloor(sqrt($n))
, ale to sprawia, że nawet dłużej kod zamiast skrócenia go; ale jeśli szerokość nie przekraczasqrt($n)
, minimalna wysokość ($j
) zawsze będzie większa niżsqrt($n)
(ich iloczyn musi wynosić co najmniej$n
);$i <= $j
(szerokość <= wysokość) jako warunku zakończenia pętli; w ten sposób szerokość będzie iterować1
do,floor(sqrt($n))
a wysokość uzyska wartości zaczynające się$n
i schodzące doceil(sqrt($n))
(niekoniecznie wszystkie);abs(width - height)
jest zawszeheight - width
($j-$i
); 5 bajtów zapisanych w ten sposób;$n
jest używana do obliczania wyniku (liczba wolnych miejsc jest równawidth * height - n
), ale nie jest potrzebna; wynik nie musi być wyświetlany, jest obliczany tylko w celu porównania rozwiązań; usuwając- n
ze wzoru wyniku zapisujemy kolejne 3 bajty (kod PHP jest-$n
), nie tracąc nic;height - width + width * height
($j-$i+$i*$j
);height - width
część wyniku maleje z każdym krokiem;||$c==$s&&$i*$j<$w*$h
- dużo bajtów);-$n
ze wzoru partytury, ocena dla pierwszego układu (1x$n
) wynosi$n-1+1*$n
(tj.2*$n-1
); początkowa wartość najlepszego wyniku ($s
) może być dowolną wartością większą lub równą2*$n
; pierwsza iteracja ma lepszy wynik i staje się najlepszym rozwiązaniem pozwalającym algorytmowi działać bez problemów z inicjalizacją.Nowy kod ( 104 bajty ) po zastosowaniu opisanych powyżej ulepszeń to:
Jest on zawinięty tutaj dla czytelności. Przygotuj powyższy kod za pomocą znacznika PHP
<?php
(technicznie nie jest to część kodu), umieść go w pliku (powiedzmyarrange-your-chairs.php
) i uruchom jako argument jako liczbę całkowitą większą niż zero. Wyświetli szerokość i wysokość obliczonego układu, oddzielone przecinkiem:Inne rozwiązanie (116 bajtów)
Inne rozwiązanie wykorzystujące inny algorytm:
Zawiera wszystkie kombinacje przynajmniej
$n
miejsc na liście asocjacyjnej; kluczem jest tekstowa reprezentacja aranżacji, wartość to wynik aranżacji. Następnie sortuje listę (rosnąco według wartości) i otrzymuje klucz pierwszego wpisu.Jeszcze jeden (115 bajtów)
To jest wersja PHP @ Neila odpowiedź (JavaScript / ES6, 85 bajtów).
Istnieją pewne zauważalne różnice związane z funkcjami każdego języka:
n
(niezdefiniowanych) wartości, a następnie używa swoich kluczy do iteracji od0
don-1
; inkrementujei
(d=(n+i++)/i|0
), aby iterować od1
don
; rozwiązanie PHP nie musi zwiększać; używarange()
do generowania tablicy, a następnie wykorzystuje wygenerowane wartości (1
don
) do iteracji;(n+i)/i
następnie konwertuje wartość na liczbę całkowitą,|0
aby uzyskać najmniejszą liczbę całkowitą większą niżn/i
; odpowiedź PHP rozwiązuje ten problem łatwo dzięki funkcji PHPceil()
; JavaScript zapewnia równieżMath.ceil()
ale zużywa 5 bajtów więcej niż rozwiązanie znalezione przez Neila;array_map()
podobną do JS,Array.map()
ale tutaj nie pomaga; jego składnia jest pełna,foreach
tworzy krótszy kod; jest jednak większy niż kod JS;||
nie jest możliwe w PHP, ponieważ brakuje operatora przecinka; Przetłumaczyłema||b||c
naif(!a&&!b)c
to, ponieważa
ib
są porównania, zanegowałem ich operatorów (zastąpionych<
przez>=
); powoduje to również większy kod niż wersja JS;$
.Niegolfowane wersje wszystkich rozwiązań i pakietu testowego można znaleźć na Github .
źródło
JavaSCript (ES6), 83 bajty
źródło
m
żeby to zrekompensować.Julia, 87 lat
Myślę, że jest to jeden krok w kierunku znalezienia magicznej funkcji dla problemu:
Patrzy tylko na pary
(i, j=(i+n)/(i+1))
lub(i, j+1)
źródło
n
Nigdzie nie definiujesz i nie wydajesz się brać wkładu.n
jako wkład. Trzeba by było to owinąćn->...
. Fajnie, że mogłeś sprawić, że to zadziała.Oracle SQL 11.2, 173 bajtów
Nie grał w golfa
źródło
Q 58 bajtów
Lamba, która oblicza minimalny koszt dla danej wartości (x) i zwraca ciąg dwóch wartości (szerokość, wysokość)
Dodanie nazwy do tej lambdy wymaga dwóch innych znaków (np. F .: {..} zamiast {..})
Test
gdzie {..} jest lambda. Odczytuje jako „stosuje lambda do każdej wartości 1 + pierwszych 100 ints” (innymi słowy do każdej wartości 1..100)
Generuje
Wyjaśnienie
Zagnieżdżona lamdba
{((b<a)?1b)#+(b:-_-x%a;a:1+!x)}
generuje wszystkie pary kandydatów (szerokość, wysokość) dla x krzeseł w dwóch sekwencjach (w1 w2 w3 ..; h1 h2 h3 ..) (szerokości i wysokości). Czytaj od lewej do prawej, ale ocenia od prawej do leweja:1+!x
generuje wartości 1..x i przypisuje tę sekwencję do-_-
to negate floor negate i implementuje ceil (ceil nie jest prymitywem języka)b:-_-x%a
stosuje pułap do każdej wartości x podzielonej przez dowolny element im a i przypisuje wynikową sekwencję do b. Innymi słowy, b oznacza pułap każdy x podzielony przez każdy 1..x+(b;a)
zwraca sekwencję złożoną z sekw. a i sek. b, a następnie odwraca ją (wynikiem jest sekwencja pary, w której i-para zawiera element i elementu a oraz element i elementu b)b<a
porównuje pozycję po pozycji b i a, i generuje sekwencję wartości logicznych (true = 1b dla każdego indeksu, gdzie b [i]s?x
zwraca pierwszą pozycję elementu x w sekwencji s. Z(b<a)?1b
Poszukujemy 1b (wartości rzeczywistej) w sekwencji wynikającej z porównania b i a, i otrzymujemy pierwszą pozycję, gdzie bn#s
pobiera n pierwszych n elementów z sekwencji. Chcemy odrzucić zduplikowane pary, więc zatrzymujemy się, gdy pierwszy element pary <drugi przedmiot (np. Rozważmy 13,1, ale nie 1,13).Jako efekt uboczny każda para wynikowej sekwencji ma malejącą odległość między aib (np. (13 1; 7 2; 5 3; 4 4)
Para kandydatów wygenerowana przez zagnieżdżoną lambda jest przypisana do c. Następnie odwracamy c (ponownie uzyskuje b, a) i stosuje do tego argumentu dwie funkcje:
*/
mnoży i-/
odejmuje. Wynikiem(-/;*/)@\:+c
jest różnica i iloczyn każdej pary.+/
jest sumą i oblicza koszt końcowy. Koszt każdego patiru przypisany jest do di / to minimum, więc
&/
d to minimalny koszt. Za pomocąd?&/d
znajdujemy pierwsze wystąpienie minimalnego kosztu w d, a za pomocą c @ .. odzyskujemy parę w tej pozycji. Ponieważ każda para ma malejącą odległość między a i n, pierwsze znalezione minimum ma maksymalną odległość między innymi parami minimalnymi, więc poprawnie stosujemy regułę remisuźródło