Cele: Wyprowadź ciąg znaków, który zawiera każdą dodatnią liczbę całkowitą ściśle poniżej 1000.
Oczywistą odpowiedzią byłoby połączenie każdego z nich, a to stworzyłoby Łańcuch 2890 znaków (dzięki manatwork), aby uniknąć tego rodzaju łatwej odpowiedzi, długość łańcucha musi być mniejsza niż 1500 znaków. Oto prosty kod Java, który generuje łańcuch znaków o długości 1200 znaków.
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import java.util.TreeSet;
import static org.junit.Assert.assertTrue;
/**
* Created with IntelliJ IDEA.
* User: fab
* Date: 05/11/13
* Time: 09:53
* To change this template use File | Settings | File Templates.
*/
public class AStringToContainThemAll {
@Test
public void testsubStrings() throws Exception {
String a = generateNewString();
boolean cool = true;
for (int i = 0; i < 1000; i++) {
assertTrue(a.contains(Integer.toString(i)));
}
}
private String generateNewString() {
List<Integer> myTree = new ArrayList<Integer>();
String finalString = new String("100");
for (int i = 10; i < 1000; i++) {
myTree.add(i);
}
while (myTree.size() > 0) {
if (finalString.contains(Integer.toString(myTree.get(0)))) {
myTree.remove(0);
} else {
String substringLong = finalString.substring(finalString.length() - 2, finalString.length());
boolean found = false;
loop:
for (Integer integer : myTree) {
if (integer.toString().startsWith(substringLong) && !finalString.contains(integer.toString())) {
finalString = finalString.concat(integer.toString().substring(2, 3));
myTree.remove(integer);
found = true;
break loop;
}
}
if(! found){
finalString = finalString.concat(myTree.get(0).toString());
myTree.remove(0);
}
}
}
return finalString;
}
}
Zwycięstwo najkrótszego kodu, punkt bonusowy za najkrótszy ciąg!
code-golf
string
kolmogorov-complexity
Fabinout
źródło
źródło
B(10, 3)
, ale ponieważ nie pozwalasz na cykliczne zawijanie, konieczne jest powtórzenie pierwszych dwóch znaków.Odpowiedzi:
Golfscript - 13 bajtów, 1315 danych wyjściowych
Powyższe wybiera liczby od 0-990, których pierwsza cyfra jest największą cyfrą liczby, tj. Ostatnia cyfra reprezentacji posortowanego łańcucha jest leksykograficznie mniejsza niż sam ciąg. Logika jest następująca:
W przypadku trzycyfrowej liczby abc , jeśli a nie jest największą cyfrą liczby, liczbę można pominąć, ponieważ zostanie ona później uwzględniona w jednym z dwóch przypadków:
b <c (np. 123 )
Ponieważ c jest największą cyfrą, numer kabiny nie zostanie pominięty. W tym przykładzie 312 nie zostanie pominięte, podobnie jak kolejna wartość 313 , która po konkatenacji ( 312 313 ) zawiera 123 .
b ≥ c (np. 132 )
Ponieważ b jest największą cyfrą, liczba bca nie zostanie pominięta. W tym przykładzie 321 nie zostanie pominięte, podobnie jak kolejna wartość 322 , która po konkatenacji ( 321 322 ) zawiera 132 . Jeśli b = c (np. 122 ), ten przypadek ma również zastosowanie. Wartość bca nie zostanie pominięta, jak poprzednio, a ponieważ a jest koniecznie mniejsza niż b , bc <a + 1> również nie zostanie pominięte. W tym przykładzie 221 222 zawiera 122 .
Ponieważ powyższy kod testuje trzecią cyfrę, a nie ostatnią, wszystkie wartości od 0 do 99 są uwzględnione w wyniku. Wartości od 1 do 99 można jednak pominąć, ponieważ jeśli występuje każda 3-cyfrowa sekwencja, wówczas każda 1-cyfrowa i 2-cyfrowa sekwencja musi być również obecna.
Wartości z 991-999 mogą być również pomijane, ponieważ są generowane przez ( 909 910 , 919 920 , ... 989 990 ).
Przy 1315 bajtach mocy wyjściowej jest to wygodnie poniżej specyfikacji problemu mniejszej niż 1500.
Wynik:
Wariant nr 1
14 bajtów, wyjście 1233
Wybierając ściśle ostatnią cyfrę do porównania, a nie trzecią, eliminuje się wiele niepotrzebnych wartości mniejszych niż 100 , co skraca otrzymany ciąg.
Wariant nr 2
16 bajtów, wyjście 1127
Odrzucając wszystkie wartości mniejsze niż 99 , powstały ciąg można jeszcze bardziej skrócić.
Golfscript - 19 bajtów, wyjście 1016
Powyższe liczy od 99 do 909 , dodając dowolną wartość, która jeszcze się nie pojawiła ( 909 normalnie byłaby ostatnią wartością dodaną w ten sposób). Przesunięcie 99 do przodu jest optymalizacją, aby uniknąć konieczności używania 910 z tyłu.
Wynik:
Golfscript 26 bajtów, wyjście 999
Zauważ, że ciąg znaków 1016 wytworzony przez poprzednie rozwiązanie jest prawie optymalny, z wyjątkiem dwóch dodatkowych cyfr dla każdej wielokrotności 111 (tj.
11111
Zamiast111
,22222
zamiast222
, itp.). Rozwiązanie można zoptymalizować, usuwając te dodatkowe cyfry (wstawiając tylko jedną cyfrę dla każdej z tych wartości zamiast trzech) i obracając909
do przodu, eliminując a9
(różni się to od poprzednich wersji, które9100
zamiast tego przesunęły się do tyłu ).Rozwinął i skomentował:
Logika wyboru, które znaki mają być dołączane, przebiega w trzech przypadkach:
Wartość z pierwszego sprawdzenia to 1 , a od drugiego -1 .
Wycinek rozpocznie się od indeksu 0 ; zwróci cały ciąg.
Wartość z pierwszego sprawdzenia wynosi 1 , a od drugiego coś ≥ 2 .
Plasterek zacznie się zaczynać od indeksu ≥ 3 ; zwróci pusty ciąg.
Wartość z pierwszego sprawdzenia to 0 , a od drugiego -1 .
Wycinek rozpocznie się od indeksu -1 ; zwróci tylko ostatnią postać.
Suma logiki jest taka, że każda wartość, która jeszcze się nie pojawiła, zostanie dodana w całości - chyba że jest wielokrotnością 111 , w którym to przypadku zostanie dodany tylko jeden znak. Wszystkie pozostałe wartości zostaną zignorowane.
Zauważ, że wyprodukowany ciąg znaków różni się od optymalnego wytworzonego przez odpowiedź Petera Taylora .
Historia:
Wynik:
źródło
GolfScript (
35 3126 znaków)Dane wyjściowe to
(1020 znaków) Jest to wariant podejścia Lyndona do konkatenacji słów: zamiast prymitywnych słów 1-znakowych używa wielokrotności 111 dla krótszego kodu, ale powtarzające się wystąpienia tych liczb; i zamiast używać minimalnych elementów grup koniugacji, używa maksymalnych elementów, ponieważ skraca to pętle.
przy 40 znakach (prawdopodobnie nadal można je poprawić) generuje optymalny ciąg, który ma długość 999 znaków:
Próba zrobienia tego w odwrotnych ciągach powoduje problemy z pominięciem wielokrotności 111.
Aby zobaczyć, że 999 jest optymalną długością (ponieważ moje krótkie komentarze powyżej nie przekonują wszystkich), zacznij od pełnej sekwencji de Bruijna, która (traktowana jako ciąg cykliczny) zawiera każdą 3-cyfrową sekwencję znaków od 0 do 9. Ponieważ jest ich 1000, musi mieć co najmniej 1000 znaków; że może być dokładnie 1000 znaków zwykle sprawdzone przez Eulera spacer na wykresie, którego węzły są sekwencje dwucyfrowe
xy
z 10 krawędziami, każdy oznaczony z jednej cyfryz
, które odbywająxy
sięyz
.Nie potrzebujemy początku sekwencji
0
, więc biorąc pod uwagę sekwencję de Bruijna, możemy obrócić, aby umieścić000
na końcu. Wtedy nie potrzebujemy żadnej z sekwencji, które zawijają się do początku, ale potrzebujemy dwóch z0
s, aby zakończyć sekwencję zaczynając od cyfry wcześniej000
, więc możemy usunąć jedną z nich, aby uzyskać ciąg 999 znaków. Wszystkie pozostałe0
są używane w liczbie, która nie zaczyna się od0
.źródło
10,:^{:x^>{x.@:&<+^>{x&@}/}/}/0.
Różnicowanie, że dla prawdziwych słów Lyndona daje10,:^{:x^>{x.@:&<+^>{.x>{x&@}*}/}/}%3>0.
(40 znaków) optymalny ciąg.GolfScript, 17 znaków
Proste podejście do dodawania każdej liczby, jeśli nie jest jeszcze obecna w ciągu (uwaga: 999 nie jest zaznaczone ani dodane, ale jest już zawarte w danych wyjściowych).
Dane wyjściowe to 1133 znaków:
źródło
Nie mam żadnego kodu, ale pomyślałem, że ktoś może docenić ten intuicyjny dowód, że 999 znaków jest dolną granicą długości danych wyjściowych:
Po pierwsze, każda 1- i 2-cyfrowa liczba jest częścią 3-cyfrowej liczby, więc zignoruj wszystko mniej niż 100. 100-999 włącznie to 900 3-cyfrowych liczb.
Najbardziej optymalnym sposobem rozwiązania problemu jest użycie każdej postaci w jak największym stopniu. Oznacza to, że liczby nakładają się na siebie tak bardzo, jak to możliwe:
Pierwszy numer doda zatem 3 znaki, a każdy kolejny numer doda 1 znak. To daje 3 + 899 = 902 znaków jako dolną granicę.
Jednak gdy jest zero, nie możemy go użyć do rozpoczęcia nowej 3-cyfrowej liczby. Możemy jednak użyć go ponownie w środku innej 3-cyfrowej liczby, o ile nie następuje po nim kolejne zero:
Ale:
Dlatego każde zero, które pojawia się na wyjściu, rozszerza wynik o 1 znak - z wyjątkiem dwóch ostatnich znaków, które mogą być zerowe, ponieważ nie nakładają się na żadne dalsze liczby:
Istnieje 81 liczb ze ściśle jednym zerem na środku (? 0?), 81 ze ściśle jednym zerem na końcu (? 0) i 9 z dwoma zerami (? 00).
Każda liczba 0 może dzielić zero z liczbą 0 numer lub liczba 00, ale nie oba. 0? i? 00 nigdy nie może dzielić zer, więc na wyjściu musi być co najmniej 81 + 9 * 2 zer.
Daje to dolną granicę 3 + 899 + 81 + 9 * 2 - 2 = 999 znaków.
Przepraszam, jeśli jest to uważane za nie na temat, ale było zbyt długo, aby zmieścić się w komentarzu.
źródło
Perl,
37 34 3332 (11361132 znaków)za $ @ (1..999) {$ _. = $ @ if! / $ @ /} printdla $ i (1..999) {$ _. = $ i jeśli! / $ i /} drukujfor (1..1e3) {$ s. = $ _ if $ s! ~ / $ _ /} print $ sWyjścia:
Krótszy ciąg:
38 3734 (1020 znaków):for ($ @ = 1e3; $ @ -;) {$ _. = $ @ if! / $ @ /} printfor ($ i = 1e3; $ i -;) {$ _. = $ i jeśli! / $ i /} drukujWyjścia:
Wciąż niezadowolony z powielania, zwłaszcza 99999 na początku! Myślę jednak, że o wiele więcej kontroli stworzyłoby o wiele więcej kodu ...
Edycja: Dodano sugestię @Peter Taylor
Edycja 2: Kilka świetnych sugestii od @primo! Dziękuję Ci
źródło
$_.=$@if!/$@/
możesz użyć powtarzania łańcucha$_.=$@x!/$@/
.for
Mogą być zastąpionewhile
jako modyfikator oświadczenie, używając modulo:...while$@=--$@%1e3
APL (20, wyjście: 1020)
Wyjaśnienie:
{∨/⍺⍷⍵:⍵⋄⍵,⍺}
: if⍺
jest podciągiem⍵
, return⍵
, else return⍵,⍺
/
: zmniejszyć ponad⍕¨
: reprezentacja ciągu każdego z nich⍳999
: liczby całkowite od1
do999
.Wynik:
APL (41, wyjście: 999)
Wyjaśnienie:
⌽⍕¨100+⍳898
:('999' '998' ... '101')
(w odwrotnej kolejności, ponieważ redukcja idzie w prawo do lewej w APL, tj.F/a b c ≡ a F (b F c)
)/
: zmniejszyć⍵,⍺⍴⍨
: prawy argument, po którym następują pierwszeN
znaki lewego argumentu, gdzieN
jest:3×~∨/⍺⍷⍵
:3
jeśli⍺
nie jest podciągiem⍵
, w przeciwnym razie0
(1=⍴∪⍺)
:1
jeśli⍺
ma tylko jeden unikalny charakter, w przeciwnym razie0
∨
: największy wspólny dzielnik dwóch poprzednich wartości, więc:1
jeśli⍺
nie jest już w nim⍵
i ma tylko jeden unikalny znak,3
jeśli⍺
nie jest już w nim,⍵
ale ma więcej niż jeden niepowtarzalny znak, w0
przeciwnym razie.'0',⍨
: dodaj zero na końcu wynikuWynik:
źródło
Rubinowy:
5046 znaków (1020 znaków wyjściowych)Przykładowy przebieg:
Testowe uruchomienie:
Rubinowy:
10297 znaków (999 znaków wyjściowych)Przykładowy przebieg:
Testowe uruchomienie:
źródło
(?0..?9*3).map{|i|$/[i]||($><<i;$/+=i)}
może?JavaScript, 39
Wynik 1020 znaków:
Weryfikacja:
for(i=0;i<1000;i++)console.assert(k.indexOf(i)>=0)
źródło
Mathematica (
6264 znaki, wyjście 1002)Ponieważ wykorzystuje to natywną funkcję, tym bardziej doceniam piękno krótszych rozwiązań od zera. Dane wyjściowe mają długość 1002 znaków.
źródło
DeBruijnSequence
zakłada się cykliczne owijanie. Dodanie „79”, ostatnich dwóch cyfr, rozwiązuje problem.Mathematica, 51 znaków
Wyjście (1155 znaków):
źródło
{i, j, k}
gdziei
wynosi od 0 do 9 orazj
,k
są mniejsze niżi
. Następnie konwertuje listę na ciąg znaków.Python - 53
63, 1134 wyjścieJest to dość brutalna siła, ale jest ważna. Tak, ma wiodące zero, ale zapisuje dwa znaki, nie mając
range(1,1000)
.Powyższe rzuca
DeprecationWarning
ponad użycie 1e3 wrange()
wywołaniu, ale ratuje postać przed użyciem 1000.Istnieje również nieco bardziej optymalna wersja wyjściowa długości, poprzez odwrócenie łańcucha kosztem
65 znaków (dzięki res i filmor za wskazówki) :Python - 58, 1021 danych wyjściowych
źródło
for i in range(999):s+=`i`*(not`i`in s)
range(999,99,-1)
zamiastrange(1000)[::-1]
.str(i)*(str(i)not in s)
jest nieco krótsza niżi=str(i);s+=[i,''][i in s]
;)1e3
zamiast1000
K, 33
Zasadniczo to samo co rozwiązanie Howardsa - 1133 znaków.
źródło
Java -
12698 znaków (Java 6)Wyjście (1020 znaków):
Może osiągnąć dobry (według Petera Taylora , ale później powiedział, że 999 jest optymalny) Długość łańcucha, dodając kilka znaków (+20 znaków dla
147118):Wyjście (1002 znaków):
Edycja : Podziękowania dla Fabinout za wskazanie, że Java 6 może zapisać 28 znaków.
źródło
public static void main(String[]a)
? (zmieniłoby to mój kod z...public static void main(String[]c){...
na...static{...
)Windows PowerShell - wyjście 40, 1020
Wynik:
źródło
Haskell, 75 bajtów - wyjście 1002
Podejście sitowe, które zwraca minimalne rozwiązanie.
Pamiętaj, że to rozwiązanie jest niepraktycznie wolne.
źródło
Data.List
dlaisInfixOf
, jednak nadal możesz zaoszczędzić 2 bajty, grając w nią jeszcze trochę: 1) Twardy kodn = 1000
2) Użyjall
ponadand
i bezdyskusyjna wersja predykatu 3) użyj(!!0)
ponadhead
4) Użyj zrozumienia listy w kombinacji zmap
&filter
5) użyj(<$>)
przezmap
:[s|s<-show<$>[1..],all((`isInfixOf`s).show)[1..1000]]!!0
PowerShell, 36 bajtów, 1020 danych wyjściowych
Wynik:
Alternatywnie, 69 bajtów, 1000 wyjść
Wynik:
Alternatywnie,
8273 bajty, wyjście 999 (minimum)Jest to uproszczony algorytm z Generuj najkrótszy De Bruijn dostosowany do stałych: alfabet =
9876543210
i długość =3
Wynik:
Skrypt testowy:
źródło
05AB1E , 9 bajtów i 1109 znaków
Wyjścia:
Wypróbuj online lub sprawdź, czy zawiera wszystkie liczby poniżej 1000 .
Wyjaśnienie:
źródło
Pyke, 13 bajtów (niekonkurujących), długość łańcucha 1133
Pyke jest nowszy niż wyzwanie i dlatego jest niekonkurencyjny.
Wypróbuj tutaj!
źródło
PHP,
4844 bajtówDzięki @primo za przypomnienie mi
ereg
.lub
wyjście: 1020 znaków. wymaga PHP <7
PHP 7, 48 bajtów:
ereg
został usunięty w PHP 7Jeśli drugi argument funkcji
strstr
(lubstrpos
innych funkcji wyszukiwania ciągów) nie jest ciągiem, zostanie użyty jako kod ascii, więc$i
wymaga rzutowania na ciąg.źródło
ereg($i,$s)
dla 4 (chciałbym również uwzględnić<?
w liczbie bajtów).ereg
został prawdopodobnie usunięty, ponieważ nazwa funkcji jest zbyt krótka i / lub nie zawierała wystarczającej liczby znaków podkreślenia. Tosplit
również zostało usunięte jest szczególnie genialne.ereg
został usunięty, ponieważ POSIX zawiera tylko podzbiór możliwości PCRE; i prawdopodobnie nie chcieli utrzymywać dwóch różnych bibliotek. Zapytam, czy jeszcze kiedykolwiek spotkam się z Rasmus Lerdorf.split
został usunięty, alejoin
pozostał (prawdopodobnie dlatego, że jest to „tylko” alias). Przepraszam za pedanterię; ale znam ludzi, którzy nie potrafią rozpoznać ironii.Groovy, 49 znaków / bajtów
Nie byłem pewien, czy zrobić to jako funkcję zwracającą zmienną łańcuchową, czy wydrukować wynik, więc to po prostu wypisuje ją na standardowe wyjście. Za pomocą wyrażenia regularnego zapisano 2 bajty, używając operatora trójskładnikowego zamiast „if” zapisano kolejny bajt. Łańcuch wyjściowy ma 1133 znaków.
Wynik:
źródło
Game Maker Language, 1014 - String 1000
show_message(909910010110210310410510610710810911121131141151161171181191201221231241251261271281291301321331341351361371381391401421431441451461471481491501521531541551561571581591601621631641651661671681691701721731741751761771781791801821831841851861871881891901921931941951961971981992002022032042052062072082092223224225226227228229230233234235236237238239240243244245246247248249250253254255256257258259260263264265266267268269270273274275276277278279280283284285286287288289290293294295296297298299300303304305306307308309333433533633733833934034434534634734834935035435535635735835936036436536636736836937037437537637737837938038438538638738838939039439539639739839940040440540640740840944454464474484494504554564574584594604654664674684694704754764774784794804854864874884894904954964974984995005055065075085095556557558559560566567568569570576577578579580586587588589590596597598599600606607608609666766866967067767867968068768868969069769869970070770870977787797807887897907987998008088098889890899900)
Również:
Ruby, 1003 - Ciąg 1000
p'909910010110210310410510610710810911121131141151161171181191201221231241251261271281291301321331341351361371381391401421431441451461471481491501521531541551561571581591601621631641651661671681691701721731741751761771781791801821831841851861871881891901921931941951961971981992002022032042052062072082092223224225226227228229230233234235236237238239240243244245246247248249250253254255256257258259260263264265266267268269270273274275276277278279280283284285286287288289290293294295296297298299300303304305306307308309333433533633733833934034434534634734834935035435535635735835936036436536636736836937037437537637737837938038438538638738838939039439539639739839940040440540640740840944454464474484494504554564574584594604654664674684694704754764774784794804854864874884894904954964974984995005055065075085095556557558559560566567568569570576577578579580586587588589590596597598599600606607608609666766866967067767867968068768868969069769869970070770870977787797807887897907987998008088098889890899900'
źródło
ruby
Kod może użyćp
zamiastputs
przekazać parametr numeryczny.