Задачи: Вывести строку, которая содержит каждое положительное целое число строго ниже 1000.
Очевидным ответом будет объединение каждого из них, и это создаст строку из 2890 символов (спасибо manatwork), чтобы избежать такого простого ответа, длина строки должна быть не более 1500 символов. Вот простой Java-код, который выводит строку из 1200 символов.
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;
}
}
Самый короткий код выигрыша, бонусное очко за самую короткую строку!
code-golf
string
kolmogorov-complexity
Fabinout
источник
источник
B(10, 3)
, но поскольку вы не разрешаете циклическую перенос, необходимо повторить первые два символа.Ответы:
Golfscript - 13 байт, 1315 вывод
Приведенное выше выбирает те числа от 0 до 990 , первая цифра которых является самой большой цифрой числа, то есть последняя цифра в представлении отсортированной строки лексикографически меньше самой строки. Логика следующая:
Для трехзначного числа abc , если a не является самой большой цифрой числа, число может быть пропущено, поскольку оно будет рассмотрено одним из двух случаев позже:
b <c (например, 123 )
Поскольку c является самой большой цифрой, номер кабины не будет пропущен. В этом примере 312 не будет пропущено, равно как и следующее значение 313 , которое при объединении ( 312 313 ) содержит 123 .
b ≥ c (например, 132 )
Поскольку b является самой большой цифрой, число bca не будет пропущено. В этом примере 321 не будет пропущено, равно как и следующее значение 322 , которое при объединении ( 321 322 ) содержит 132 . Если b = c (например, 122 ), этот случай также применяется. Значение bca не будет пропущено, как раньше, и, поскольку a обязательно меньше, чем b , bc <a + 1> также не будет пропущено. В этом примере 221 222 содержит 122 .
Поскольку приведенный выше код проверяет третью цифру, а не только последнюю, все значения от 0 до 99 включаются в результат. Однако значения от 1 до 99 могут быть пропущены, поскольку, если присутствует каждая трехзначная последовательность, то должны присутствовать также каждая однозначная и двухзначная последовательность.
Значения от 991-999 также могут быть пропущены, так как они генерируются ( 909 910 , 919 920 , ... 989 990 ).
При 1315 байтах вывода это удобно при спецификации задачи менее 1500.
Выход:
Вариация № 1
14 байт, вывод 1233
При выборе строго последней цифры для сравнения, а не третьей, многие из ненужных значений, меньших 100 , удаляются, сокращая результирующую строку.
Вариация № 2
16 байтов, 1127 вывод
Путем предварительного извлечения всех значений, меньших 99 , полученная строка может быть сокращена еще больше.
Golfscript - 19 байт, 1016 вывод
Выше указано от 99 до 909 , добавляя любое значение, которое еще не появилось ( 909 обычно будет последним добавленным значением таким образом). Перемещение 99 вперед - это оптимизация, чтобы избежать необходимости 910 сзади.
Выход:
Golfscript 26 байт, 999 вывод
Обратите внимание, что строка символов 1016, созданная в предыдущем решении, является почти оптимальной, за исключением двух дополнительных цифр для каждого, кратного 111 (т. Е.
11111
Вместо111
,22222
вместо222
и т. Д.). Решение можно сделать оптимальным, удалив эти дополнительные цифры (вставляя только одну цифру в каждое из этих значений вместо трех), и поворачивая909
вперед, удаляя9
(это отличается от предыдущих версий, которые9100
вместо этого переместились на заднюю часть). ).Развернул и прокомментировал:
Логика выбора символов для добавления выполняется в трех случаях:
Значение из первой проверки равно 1 , а из второй -1 .
Срез начнется с индекса 0 ; он вернет всю строку.
Значение из первой проверки равно 1 , а из второй что-то ≥ 2 .
Срез начнется с индекса ≥ 3 ; он вернет пустую строку.
Значение первой проверки равно 0 , а второй -1 .
Срез начнется с индекса -1 ; он вернет только последний символ.
Сумма логики заключается в том, что любое значение, которое еще не появилось, будет добавлено целиком - если только оно не кратно 111 , в этом случае будет добавлен только один символ. Все остальные значения будут игнорироваться.
Обратите внимание, что полученная строка отличается от оптимальной, полученной из ответа Питера Тейлора .
История:
Выход:
источник
GolfScript (
35 3126 символов)Выход
(1020 символов) Это вариант подхода объединения слов Линдона: вместо использования примитивных 1-символьных слов он использует кратные 111 для более короткого кода, но повторяющиеся вхождения этих чисел; и вместо того, чтобы использовать минимальные элементы групп сопряженности, он использует максимальные элементы, потому что это сокращает циклы.
в 40 символов (возможно, все еще может быть улучшен) генерирует оптимальную строку длиной 999 символов:
Попытка заставить это сделать обратные строки наталкивается на проблемы с пропуском, кратным 111.
Чтобы увидеть, что 999 является оптимальной длиной (поскольку мои краткие комментарии выше не убеждают всех), начните с полной последовательности де Брюина, которая (взятая как циклическая строка) содержит каждую 3-значную последовательность символов от 0 до 9. их 1000, длина должна быть не менее 1000 символов; тот факт, что длина может быть ровно 1000 символов, обычно подтверждается эйлеровым блужданием на графе, узлы которого представляют собой двузначные последовательности
xy
с 10 ребрами, каждое из которых помечено одной цифройz
,xy
к которой относитсяyz
.Нам не нужно начинать последовательности
0
, поэтому, учитывая последовательность де Брюина, мы можем повернуть, чтобы поставить000
в конце. Тогда нам не нужна ни одна из последовательностей, которые переносятся в начало, но нам нужны две из0
s, чтобы завершить последовательность, начинающуюся с цифры раньше000
, поэтому мы можем удалить одну из них, чтобы получить строку из 999 символов. Все остальные0
используются в числе, которое не начинается с0
.источник
10,:^{:x^>{x.@:&<+^>{x&@}/}/}/0.
которое для истинных слов Линдона дает10,:^{:x^>{x.@:&<+^>{.x>{x&@}*}/}/}%3>0.
(40 символов) для оптимальной строки.GolfScript, 17 символов
Простой подход к добавлению каждого числа, если оно еще не присутствует в строке (примечание: 999 не проверяется и не добавляется, но уже содержится в выходных данных).
Вывод 1133 символа:
источник
У меня нет никакого кода, но я подумал, что кто-то может оценить это интуитивное доказательство того, что 999 символов - это нижняя граница длины вывода:
Во-первых, каждое однозначное и двузначное число является частью трехзначного числа, поэтому игнорируйте все, что меньше 100. 100-999 включительно - это 900 трехзначных чисел.
Самый оптимальный способ решить эту проблему - это использовать как можно больше символов. Это означает, что числа перекрываются как можно больше, например так:
Поэтому к первому номеру добавляются 3 символа, а к каждому последующему числу добавляется 1 символ. Это дает 3 + 899 = 902 символа в качестве нижней границы.
Однако, когда есть ноль, мы не можем использовать его, чтобы начать новый 3-значный номер. Мы можем повторно использовать его в середине другого трехзначного числа, если за ним не следует еще один ноль:
Но:
Поэтому каждый ноль, который появляется в выходных данных, расширяет вывод на 1 символ - за исключением двух последних символов, которые могут быть нулевыми, поскольку они не перекрывают дальнейшие числа:
Есть 81 число со строго одним нулем в середине (? 0?), 81 со строго одним нулем в конце (?? 0) и 9 с двумя нулями (? 00).
Каждое число «0» может делить ноль с «0» число или число? 00, но не оба. ? 0? и? 00 никогда не может делить нули, поэтому в выходных данных должно быть не менее 81 + 9 * 2 нулей.
Это дает нижнюю границу 3 + 899 + 81 + 9 * 2 - 2 = 999 символов.
Извинения, если это считается не по теме, но это было слишком долго, чтобы вписаться в комментарий.
источник
Perl,
37 34 3332 (11361132 символа)для $ @ (1..999) {$ _. = $ @, если! / $ @ /} печатьдля $ i (1..999) {$ _. = $ i if! / $ i /} распечататьдля (1..1e3) {$ s. = $ _ если $ s! ~ / $ _ /} напечатать $ sВыходы:
Более короткая строка:
38 3734 (1020 символов):для ($ @ = 1E3; $ @ -;) {$ _ = $ @, если / $ @ /.!} печатьfor ($ i = 1e3; $ i -;) {$ _. = $ i if! / $ i /} printВыходы:
Все еще не доволен дублированием, особенно 99999 в начале! Я думаю, что гораздо больше проверок создаст намного больше кода, хотя ...
Редактировать: Добавлено предложение от @Peter Taylor
Редактировать 2: Несколько замечательных предложений от @primo! Спасибо
источник
$_.=$@if!/$@/
вы можете использовать повторение строк$_.=$@x!/$@/
.for
Может быть заменен наwhile
качестве модификатора заявления, используя по модулю:...while$@=--$@%1e3
APL (20, выход: 1020)
Объяснение:
{∨/⍺⍷⍵:⍵⋄⍵,⍺}
: if⍺
является подстрокой⍵
, return⍵
, else return⍵,⍺
/
: уменьшить сверх⍕¨
: строковое представление каждого из⍳999
: целые числа от1
до999
.Выход:
APL (41, выход: 999)
Объяснение:
⌽⍕¨100+⍳898
:('999' '998' ... '101')
(в обратном порядке, потому что сокращение идет справа налево в APL, т.е.F/a b c ≡ a F (b F c)
)/
: уменьшить⍵,⍺⍴⍨
: правый аргумент, за которым следуют первыеN
символы левого аргумента, гдеN
:3×~∨/⍺⍷⍵
:3
если⍺
не является подстрокой⍵
, в противном случае0
(1=⍴∪⍺)
:1
если⍺
есть только один уникальный характер, в противном случае0
∨
: наибольший общий делитель двух предыдущих значений, поэтому:1
if⍺
еще не введен⍵
и имеет только один уникальный символ,3
если⍺
еще не введен,⍵
но имеет более одного уникального символа, в0
противном случае.'0',⍨
: добавить ноль в конец результатаВыход:
источник
Рубин:
5046 символов (вывод 1020 символов)Образец прогона:
Тестовый забег:
Рубин:
10297 символов (вывод 999 символов)Образец прогона:
Тестовый забег:
источник
(?0..?9*3).map{|i|$/[i]||($><<i;$/+=i)}
может быть?JavaScript, 39
Вывод 1020 символов:
Проверка:
for(i=0;i<1000;i++)console.assert(k.indexOf(i)>=0)
источник
Mathematica (
6264 символа, 1002 выхода)Поскольку для этого используется нативная функция, я все больше ценю красоту более коротких решений с нуля. Выход составляет 1002 символа.
источник
DeBruijnSequence
предполагается циклическая упаковка. Предварительная «79», последние две цифры, решает проблему.Mathematica, 51 символ
Выход (1155 символов):
источник
{i, j, k}
гдеi
находится от 0 до 9 иj
,k
меньшеi
. Затем он преобразует список в строку.Python - 53
63Выход 1134Это довольно грубо, но это действительно так. Да, он имеет ведущий ноль, но он сохраняет два символа, не имея
range(1,1000)
.Приведенное выше бросает более
DeprecationWarning
чем использование 1e3 вrange()
вызове, но сохраняет символ более 1000.Также есть немного более оптимальная версия вывода длины, путем изменения строки за счет
65 символов (спасибо res и filmor за советы) :Python - 58, выход 1021
источник
for i in range(999):s+=`i`*(not`i`in s)
range(999,99,-1)
вместоrange(1000)[::-1]
.str(i)*(str(i)not in s)
немного корочеi=str(i);s+=[i,''][i in s]
;)1e3
вместо1000
К, 33
В основном то же, что и решение Howards - 1133 символа.
источник
Java -
12698 символов (Java 6)Выход (1020 символов):
Может достичь хорошего (по словам Питера Тейлора , но позже он сказал, что 999 был оптимальным) Длина строки, добавив несколько символов (+20 символов для
147118):Выход (1002 символа):
Редактировать : Спасибо Fabinout за указание, что Java 6 может сохранить 28 символов.
источник
public static void main(String[]a)
? (это изменило бы мой код с...public static void main(String[]c){...
на...static{...
)Windows PowerShell - 40, выход 1020
Выход:
источник
Haskell, 75 байт - выход 1002
Сетчатый подход, который возвращает минимальное решение.
Обратите внимание, что это решение нереально медленно.
источник
Data.List
forisInfixOf
, однако вы все равно можете сэкономить 2 байта, играя в гольф еще немного: 1) Жесткий кодn = 1000
2) Использоватьall
болееand
и бессмысленную версию предиката 3) Использовать(!!0)
болееhead
4) Использовать понимание списка вместо комбинацииmap
&filter
5) использовать(<$>)
болееmap
:[s|s<-show<$>[1..],all((`isInfixOf`s).show)[1..1000]]!!0
Powershell, 36 байт, 1020 вывод
Выход:
Альтернатива, 69 байтов, 1000 выходных
Выход:
Альтернатива,
8273 байта, 999 выводов (минимум)Это упрощенный алгоритм из « Генерации кратчайшего де Брюйна», адаптированный для констант: алфавит =
9876543210
и длина =3
Выход:
Тестовый скрипт:
источник
05AB1E , 9 байтов и 1109 символов
Выходы:
Попробуйте онлайн или убедитесь, что он содержит все числа ниже 1000 .
Объяснение:
источник
Пайк, 13 байтов (неконкурентный), длина строки 1133
Пайк новее, чем вызов и, следовательно, неконкурентоспособен.
Попробуй это здесь!
источник
PHP,
4844 байтаСпасибо @primo за напоминание
ereg
.или
Выход: 1020 символов. требует PHP <7
PHP 7, 48 байт:
ereg
был удален в PHP 7Если второй аргумент
strstr
(илиstrpos
других функций поиска строк) не является строкой, он будет использоваться как код ascii, поэтому$i
требуется приведение к строке.источник
ereg($i,$s)
для 4 (я бы также включил<?
в подсчет байтов).ereg
был удален, предположительно, из-за того, что имя функции слишком короткое и / или не содержит достаточного подчеркивания. Этоsplit
было также удалено, особенно блестяще.ereg
был удален, потому что POSIX содержит только подмножество возможностей PCRE; и они, вероятно, не хотели поддерживать две разные библиотеки. Я спрошу, должен ли я когда-нибудь снова встретиться с Расмусом Лердорфом.split
был удален, ноjoin
остался (вероятно, потому что это «только» псевдоним). Извините за педантизм; но я знаю людей, которые не могут распознать иронию.Groovy, 49 символов / байт
Я не был уверен, делать ли это как функцию, возвращающую строковую переменную, или распечатывать результат, так что это просто выводит его на стандартный вывод. С помощью сопоставителя регулярных выражений удалось сохранить 2 байта, используя троичный оператор вместо «если» сохранил другой байт. Выходная строка - 1133 символа.
Выход:
источник
Game Maker Language, 1014 - Строка 1000
show_message(909910010110210310410510610710810911121131141151161171181191201221231241251261271281291301321331341351361371381391401421431441451461471481491501521531541551561571581591601621631641651661671681691701721731741751761771781791801821831841851861871881891901921931941951961971981992002022032042052062072082092223224225226227228229230233234235236237238239240243244245246247248249250253254255256257258259260263264265266267268269270273274275276277278279280283284285286287288289290293294295296297298299300303304305306307308309333433533633733833934034434534634734834935035435535635735835936036436536636736836937037437537637737837938038438538638738838939039439539639739839940040440540640740840944454464474484494504554564574584594604654664674684694704754764774784794804854864874884894904954964974984995005055065075085095556557558559560566567568569570576577578579580586587588589590596597598599600606607608609666766866967067767867968068768868969069769869970070770870977787797807887897907987998008088098889890899900)
Также:
Рубин, 1003 - Строка 1000
p'909910010110210310410510610710810911121131141151161171181191201221231241251261271281291301321331341351361371381391401421431441451461471481491501521531541551561571581591601621631641651661671681691701721731741751761771781791801821831841851861871881891901921931941951961971981992002022032042052062072082092223224225226227228229230233234235236237238239240243244245246247248249250253254255256257258259260263264265266267268269270273274275276277278279280283284285286287288289290293294295296297298299300303304305306307308309333433533633733833934034434534634734834935035435535635735835936036436536636736836937037437537637737837938038438538638738838939039439539639739839940040440540640740840944454464474484494504554564574584594604654664674684694704754764774784794804854864874884894904954964974984995005055065075085095556557558559560566567568569570576577578579580586587588589590596597598599600606607608609666766866967067767867968068768868969069769869970070770870977787797807887897907987998008088098889890899900'
источник
ruby
Код можно использоватьp
вместоputs
передачи числового параметра.