Автограмма программы


34

В этом предложении используются два а, два с, два, двадцать восемь, пять, три, восемь, восемь, одиннадцать, три, два, тринадцать, девять, два, пять, двадцать пять s, двадцать три т, шесть v, десять w, два x, пять y и один z.

Такие предложения называются автограммами . Ваша задача - написать программу или функцию, имеющую аналогичное свойство: она принимает в качестве входных данных байт и выводит целое число, представляющее число раз, которое этот байт появляется в исходном коде программы. Он должен вывести 0, если его вход не отображается в источнике.

Ваша программа не должна читать свой собственный исходный код , прямо или косвенно, но вместо этого все данные, необходимые для вывода, должны быть жестко запрограммированы в стиле quine. Ваша программа должна быть длиной не менее одного байта.

Это , поэтому выигрывает самая короткая запись (в байтах). Я не приму ответ, поэтому смело боритесь за самое короткое решение на вашем любимом языке.

Настоятельно рекомендуется включить объяснение в свой пост.

Leaderboards

Ниже приведены таблицы лидеров как по общему количеству очков, так и по языкам:


5
Песочница . (Он был там с 2014 года!)
Натаниэль

Разрешены ли функции или только полные программы?
Уриэль

1
Примечание. Ответы, подобные этому, больше не считаются действительными.
user202729

1
FWIW, правильное определение quine является немного более сильным, чем я действительно хотел бы для этой проблемы. Например, я был бы очень рад увидеть программу, которая использует все символы в некотором смежном диапазоне и просто выводит 1, если его вход находится в этом диапазоне, даже если у этого нет «раздела программы, который кодирует другая часть программы ". По этой причине я был бы готов привести пример с сетчаткой, хотя это было бы неутешительно, если бы это оттолкнуло других от публикации, так как уже было всего 1 байт. (@ user202729)
Натаниэль

1
Из-за моего комментария выше, я удалил утверждение, что применяются правила quine. (Я сохранил часть о том, что не читаю исходный код.)
Натаниэль

Ответы:


15

Октава , 44 байта

@(x)sum([[39,'(())*,239==@[[]]msuxx']]==x)*2

Попробуйте онлайн!

Результат функции, при использовании каждого из символов в функции в качестве ввода:

'  (  )  *  ,  2  3  9  =  @  [  ]  m  s  u  x  
2  4  4  2  2  2  2  2  4  2  4  4  2  2  2  4  

Все остальные входные символы возвращают ноль.

Тот факт, что мне пришлось бежать, 'сделал это намного дольше. Чтобы учесть 4 скобки, у меня просто был дубликат в строке. Однако дублирование апострофов требует апострофов, так что это только уводит нас от правильного результата. Поэтому мне пришлось подсчитать количество апострофов с его ASCII-значение, 39. Это, конечно, означало, что мне нужно было проверять персонажей 3и 9делать это намного дольше.


2
Это то, что я надеюсь увидеть больше. (Оптимизация для решения проблемы, вместо того, чтобы просто взять стандартную квинну и добавить код для подсчета символов.)
Натаниэль

7

Excel, 84 байта

=IFERROR(MID("65496331125442343343233",FIND(A1,"""123456789,()=MINORFADEOMEN"),1),0)

Find()будет искать значение в ячейке A1в строке "123456789,()=MINORFADEOMEN( """в начале это экранирующий символ и будет вычисляться просто ").

Основываясь на результатах Find(), то Mid()функция возвращает соответствующий символ из строки чисел. Эта строка была создана путем итерации, пока она не перестала изменяться.

Если символ in A1не найден, Find()возвращает ошибку, поэтому IfError()функция избегает ее возврата 0.

В OMENконце строки, в которой выполняется поиск в Find()функции, присутствуют повторяющиеся буквы, поэтому их позиция никогда не будет возвращена, но они были необходимы для настройки количества символов. Без них существовал бесконечный цикл смены чисел. Буквенное расположение - стилистический выбор.


5

JavaScript (ES6), 70 байт

Не читает источник функции, но это довольно долго. Принимает ввод в виде 1-символьной строки.

i=>~(n='\\34=\'in(|)0257?:.>[]Odefx~'.indexOf(i))?'3733544333'[n]||2:0

Попробуйте онлайн!


Вы можете сократить эту связку, переделав немного, чтобы уменьшить количество различных символов: i=>'36335633'[i='\\36=\'i|&()25.>[]Odefx~n'.indexOf(i)]||~i&&2(сохранено 8 байт)
Yair Rand,

5

Сетчатка , 1 байт

Это было бы недопустимо, если бы строго следовал правилам квина, но ОП явно разрешил это в комментарии .

x

Попробуйте онлайн!

В сетчатке однострочная программа подсчитывает вхождения этого регулярного выражения во входных данных. Эта задача решается с помощью какого - либо одного символа ASCII , за исключением `, ., +, *, ?, [, (, ), ^, $, \и символ новой строки.


5

C # (компилятор Visual C #) , 88 57 байт

x=>"\\\"(())==>>??..::3300CCaaiinoossttx".Contains(x)?3:0

Попробуйте онлайн!

Возвращает 3, если строка содержит переданный символ, в противном случае возвращает 0. Строка содержит каждый символ кода по крайней мере один раз и точно столько, сколько требуется, чтобы символ был 3 раза в коде.

-31 байт благодаря Кевину Круйссену


Хороший подход! +1 от меня. Вы можете сэкономить несколько байтов, убрав круглые скобки (a)=>и взяв ввод в виде строки вместо символа, чтобы больше не нуждаться .ToString()(и, a+""возможно, также использовать его для задач кода-гольфа, которые вам никогда не понадобятся .ToString()). Кроме того, так как .Containsуже содержит aпеременную, вы можете сделать входную переменную другим неиспользуемым символом (например, xили q), чтобы иметь 3 для каждого символа вместо 4. РЕДАКТИРОВАТЬ: не берите в голову последнюю часть, я вижу, что "она также используется 4 раза.
Кевин Круйссен

@KevinCruijssen Спасибо за совет. Но допустима ли строка в качестве входных данных? Учитывая, что OP попросил ввести байт?
Hyarus

Пока это одна строка символов, я уверен, что это так. Большинство языков в любом случае могут вводить только строковые значения, а некоторые, в которых есть символы, по-прежнему предпочитают вводить в виде строки (например, Java, JavaScript и Japt. Форматы ввода и вывода обычно довольно гибкие. Но вы всегда можете задать OP в прокомментируйте, если вы все еще сомневаетесь. :)
Кевин Круйссен

1
@KevinCruijssen звучит разумно. И если мы избежим одного из «мы можем даже получить до 3 желаемых за символ
Hyarus

2
Односимвольные строки в качестве ввода меня устраивают.
Натаниэль

4

Haskell , 66 байт

Первые две версии, по сути, представляют собой quine, которая фильтрует необходимые символы, а затем принимает длину:

q c=length.filter(==c)$id<>show$"q c=length.filter(==c)$id<>show$"

Попробуйте онлайн или протестируйте со всеми персонажами! *


Альтернатива без (<>), 72 байта

q c=length.filter(==c)$(++)<*>show$"q c=length.filter(==c)$(++)<*>show$"

Попробуйте онлайн или протестируйте со всеми персонажами!


Альтернатива не Quine, 87 86 байт

Возможно, все еще будет улучшено, но я рад, что получил его только в трех разных группах.

Мне больше нравится этот, хотя он насчитывает больше байтов. Он вычисляет количество символов / байтов как сумму 2,3 и 7 (обратите внимание, что некоторые символы находятся в нескольких группах):

u t=sum[fst e|e<-[(2," ()-237<=dflnst|"),(3," ()[\\]`mstu"),(7,"\",ee")],t`elem`snd e]

Попробуйте онлайн или протестируйте со всеми персонажами!


* импорт, (<>)потому что версия TIO GHC - 8.0.2


3

Python 2 , 54 52 32 байта

-20 байт благодаря овсу

("''+.23cnotu()"*2+'"*'*3).count

Попробуйте онлайн!


1
Почему у вас нет ни лямбда, ни ввода?
Стьюи Гриффин

2
@StewieGriffin Python автоматически связывает ссылку на метод, поэтому "xxx".countэквивалентен lambda c:"xxx".count(c).
Нил

@StewieGriffin и вы используете оба одинаково -> f="xxx".countи f=lambda c:"xxx".count(c)будет называтьсяf('a')
Род

3

Шелуха , 11 10 8 байт

Спасибо Лео за -2 байта!

#sD"#sD"

Попробуйте онлайн!

объяснение

Это гарантирует, что он использует только ASCII (потому что showэто испортит его), и что каждый символ содержится дважды:

#sD"#sD"  -- character as input, eg. '"'
   "#sD"  -- string literal (note the redundant '"'): "#sD"
  D       -- double: "#sD#sD"
 s        -- show: "\"#sD#sD\""
#         -- number of occurences: 2

Стандартное расширение Quine, 11 байт

#hS+s"#hS+s

Попробуйте онлайн!

объяснение

#hS+s"#hS+s  -- character as input, eg. '"'
     "#hS+s  -- string literal: "#hS+s"
  S+         -- join with itself: ("#hS+s"++)
    s        -- | and itself shown: "\"#hS+s\""
             -- : "#hS+s\"#hS+s\""
 h           -- init: "#hS+s\"#hS+s"
#            -- number of occurences in string: 1

1
Вы можете управлять цитатами проще, удвоив строку перед ее отображением: попробуйте онлайн!
Лев

3

Java 10, 164 81 57 байт

q->"q-->>\\\"..ccoonttaaiiss(())??33::00".contains(q)?3:0

Порт @Hyarus 'C # ответа , поэтому обязательно проголосуйте за него!

Объяснение:

Попробуйте онлайн.

q->      // Method with String parameter and integer return-type
  "q->\\\"..ccoonttaaiiss(())??33::00".contains(q)?
         //  If the string above contains the input character
   3     //   Return 3
  :      //  Else:
   0     //   Return 0

Старый 164-байтовый ответ:

c->{var s="c->{var s=%c%s%1$c;return s.format(s,34,s).replaceAll(%1$c[^%1$c+c+']',%1$c%1$c).length();}";return s.format(s,34,s).replaceAll("[^"+c+']',"").length();}

Объяснение:

Попробуйте онлайн.

c->{                                  // Method with char parameter and integer return-type
  var s="c->{var s=%c%s%1$c;return s.format(s,34,s).replaceAll(%1$c[^%1$c+c+']',%1$c%1$c).length();}";
                                      //  Unformatted source code
  return s.format(s,34,s)             //  Create the formatted source code (the quine),
          .replaceAll("[^"+c+']',"")  //  remove all characters not equal to the input,
          .length();}                 //  and return the length

-часть:

  • Строка sсодержит неформатированный исходный код.
  • %sиспользуется для ввода этой строки в себя с помощью s.format(...).
  • %c, %1$cИ 34используются для форматирования двойных кавычек.
  • s.format(s,34,s) складывает все вместе

Задание часть:

  • .replaceAll("[^"+c+']',"") удаляет все символы кроме тех, которые равны вводу.
  • .length() затем принимает длину этой строки.

ПРИМЕЧАНИЕ: .split(c).lengthStringвводом вместо char) может показаться короче, но имеет две проблемы:

  1. Первый символ дает неверный результат, поэтому, если cc->ведущей частью) вводится, он неверно вернет один символ слишком мало. Это можно исправить, добавив +(c==99?1:0)как исходный код, так и неформатированный исходный код String (и изменив .split(c)на .split(c+""), но тогда у нас все еще будет следующая проблема:
  2. Если вводится символ регулярного выражения (т. Е. $), Он .splitбудет интерпретироваться как регулярное выражение, давая неверный результат.

3

Haskell , 58 байт

f c=sum[2|x<-succ '!':"f c=sum[2|x<-succ '!':,x==c]",x==c]

Попробуйте онлайн! или проверьте решение .

Те же варианты подсчета байтов:

f c=sum[2|x<-tail$show"f c=sum[2|x<-tail$show,x==c]",x==c]
f c=sum[1|x<-id<>show$"f c=sum[1|x<-id<>show$,x==c]",x==c]

Haskell , 90 байт

sum.($zip"1234\"$,.[\\]opu+()iklmsz652"$[4,4,11,3,3,3,16,5,3,3,3,3,3,3,3]++[2,2..]).lookup

Попробуйте онлайн! или проверьте решение . Использует тот факт, что sum Nothing = 0и, например,sum (Just 4) = 4 .


3

Болтовня , 112 132 байта

Smalltalk не совсем известен своей пригодностью для игры в гольф :-)

Метод, определенный в классе Character (протестирован в VA Smalltalk и Squeak, должен работать и на других диалектах, таких как VisualWorks и Pharo):

a^(0to:6),#(10 18)at:(#('' ',[]^|+68cForu' '#0adefln' '1it' '()' ':s' ' ' '''')findFirst:[:s|s includes:self])+1

Символы, встречающиеся в источнике, группируются по количеству вхождений. Группы тестируются для первой, которая содержит получателя, и возвращается соответствующий счетчик вхождений.

Старый метод:

a^('''''((((())))):::[[[[]]]]^^^^^0000066666aaaacccccdddddeefffFFFFFiiilllnnnnnrrrrrsssTTTTTuuuu'includes:self)ifTrue:[6]ifFalse:[0]

Каждый символ, который появляется в методе, появляется ровно 6 раз (повторяется в строковой константе), поэтому метод просто проверяет, содержится ли получатель в строке, и возвращает 6, если это так, 0 в противном случае.

После определения метода, как указано выше, вы можете проверить его, используя

| code |
code := Character sourceCodeAt: #a.
((0 to: 255) collect: [:b | b asCharacter]) reject: [:c | c a = (code occurrencesOf: c)]

Результат должен быть пустым.


1
Добро пожаловать в PPCG!
Мартин Эндер,

2

JavaScript, 31 байт

f=c=>~-`f=${f}`.split(c).length

Попробуйте онлайн


1
Я думаю, что это читает собственный исходный код, не так ли? Это явно запрещено, жирным шрифтом, в вопросе.
Натаниэль

1
@ Натаниэль, посмотри здесь .
Лохматый

2
Хм. Честно говоря, я думаю, что это глупо, но я не могу не согласиться с мета-консенсусом, я полагаю.
Натаниэль

1
@Nathaniel Для всех программ, которые облегчают eval, они также упрощают quine.
user202729

1
@ user202729 Я не думаю, что следует, не так ли? Вы не можете сделать тот же трюк в Python, например. Это обратный eval, а не eval
Натаниэль



2

Haskell , 96 байт

n"n"=15;n"="=14;n" "=2;n";"=13;n"\\"=3;n"\""=25;n"0"=2;n"1"=4;n"2"=4;n"3"=4;n"4"=5;n"5"=5;n n3=0

Попробуйте онлайн!

Haskell , 109 байт

n 'n'=15;n '='=14;n ' '=14;n ';'=13;n '\\'=3;n '\''=25;n '0'=2;n '1'=5;n '2'=4;n '3'=4;n '4'=5;n '5'=5;n n3=0

Попробуйте онлайн!

Haskell , 122 байта

n 'n'=21
n '='=14
n ' '=14
n '\n'=12
n '\\'=4
n '\''=32
n '0'=2
n '1'=5
n '2'=5
n '3'=3
n '4'=5
n '5'=5
n nnnnnn4'''''''=0

Попробуйте онлайн!

Пояснения

Эти ответы не очень сложны. Это серия объявлений, по одному на каждый символ, присутствующий в программе. В конце у нас есть catch, который возвращает 0 для символов, которых нет в программе.

Я использую несколько приемов, чтобы минимизировать количество символов, необходимых в программе, и оттуда я возился с вещами, пока цифры не оказались правильными. Вы можете видеть, что я добавил имя переменной в последнем объявлении во всех трех из них. Разница между этими 3 программами заключается в том, выбрал ли я новую строку или ;для разрыва строки, и решил ли я использовать в качестве входных данных символы или строки. Такой ;подход не кажется по своей сути превосходящим другие, он просто приносит удачу и в итоге оказывается короче, однако кажется, что использование Strings - лучшая идея, чем Chars, потому что Chars требуют пробелов после имени функции, а Strings - нет.


: | что случилось с вашим правописанием в объяснении
только ASCII

2

Пробел , 140 байт

[S S S N
_Push_0][S N
S _Duplicate][S N
S _Duplicate][T N
T   S _Read_STDIN_as_character][T   T   T   _Retrieve][S S S T  S S T   N
_Push_9][T  S S T   _Subtract][S N
S _Duplicate][N
T   S S T   N
_If_0_Jump_to_Label_TAB][S S S T    N
_Push_1][T  S S T   _Subtract][S N
S _Duplicate][N
T   S S N
_If_0_Jump_to_Label_NEWLINE][S S S T    S T T   S N
_Push_22][T S S T   _Subtract][N
T   S T N
_If_0_Jump_to_Label_SPACE][N
S T N
_Jump_to_Label_PRINT][N
S S S T N
_Create_Label_TAB][S S S T  S S T   S T N
_Push_37][N
S T N
_Jump_to_Label_PRINT][N
S S S N
_Create_Label_NEWLINE][S S S T  S S S S T   N
_Push_33][N
S T N
_Jump_to_Label_PRINT][N
S S T   N
_Create_Label_SPACE][S S S T    S S S T T   S N
_Push_70][N
S S N
_Create_Label_PRINT][T  N
S T _Print_as_integer]

Буквы S(пробел), T(табуляция) и N(новая строка) добавляются только как подсветка.
[..._some_action]добавлено только в качестве объяснения.

70 пробелов, 37 вкладок и 33 новых строки.

Обычно я использую Создать ярлыки в порядке NSSN, NSSSN, NSSTN, NSSSSN, NSSSTN, NSSTSN,NSSTTN и т.д. Но так как печать номер , в котором двоичный S=0/ T=1используется влияет на количество , мне нужно вывести, я использовал этикетки NSSN, NSSSN, NSSTNи NSSSTNвместо того , который дал идеальное количество пробелов / табуляций для двоичных чисел SSSTSSSSTN(33; количество новых строк), SSSTSSTSTN(37; количество табуляций) и SSSTSSSTTSN(70; количество пробелов).

Объяснение в псевдокоде:

Character c = STDIN-input as character
If c is a tab:
  Print 37
Else if c is a new-line:
  Print 33
Else if c is a space:
  Print 70
Else
  Print 0

Пример работы:

Вход: пробел

Command       Explanation                   Stack       Heap     STDIN   STDOUT   STDERR

SSSN          Push 0                        [0]
SNS           Duplicate top (0)             [0,0]
SNS           Duplicate top (0)             [0,0,0]
TNTS          Read STDIN as character       [0,0]       {0:32}   \n
TTT           Retrieve                      [0,32]      {0:32}
SSSTSSTN      Push 9                        [0,32,9]    {0:32}
TSST          Subtract top two (32-9)       [0,23]      {0:32}
SNS           Duplicate top (23)            [0,23,23]   {0:32}
NTSSTN        If 0: Jump to Label_TAB       [0,23]      {0:32}
SSSTN         Push 1                        [0,23,1]    {0:32}
TSST          Subtract top two (23-1)       [0,22]      {0:32}
SNS           Duplicate top (22)            [0,22,22]   {0:32}
NTSSN         If 0: Jump to Label_NEWLINE   [0,22]      {0:32}
SSSTSTTSN     Push 22                       [0,22,22]   {0:32}
TSST          Subtract top two (22-22)      [0,0]       {0:32}
NTSTN         If 0: Jump to Label_SPACE     [0]         {0:32}
NSSTN         Create Label_SPACE            [0]         {0:32}
SSSTSSSTTSN   Push 70                       [0,70]      {0:32}
NSTN          Jump to Label_PRINT           [0,70]      {0:32}
NSSN          Create Label_PRINT            [0,70]      {0:32}
TNST          Print as integer              [0]         {0:32}            70
                                                                                  error

Программа останавливается с ошибкой: выход не определен.
Попробуйте онлайн (только с необработанными пробелами, вкладками и новыми строками).

Вход: вкладка

STDIN будет \t( 9) вместо этого, и в этом случае он будет 0на первомIf 0 проверке, перейдет в LABEL_TAB/ NSSSTNи будет нажимать и печатать37 вместо этого .

Попробуйте онлайн (только с необработанными пробелами, вкладками и новыми строками).

Ввод: новая строка

Вместо этого будет STDIN \n( 10), в этом случае он будет 0при второй If 0проверке, перейдет к Label_NEWLINE/ NSSSNи будет нажимать и печатать33 вместо этого .

Попробуйте онлайн (только с необработанными пробелами, вкладками и новыми строками).

Вход: все остальное

Любой другой символ ввода будет делать NSTN(Перейти к Label_PRINT) после третьей If 0проверки, печатая0 который все еще был в стеке (который мы продублировали в самом начале).

Попробуйте онлайн (только с необработанными пробелами, вкладками и новыми строками).


1
Это отличный язык для этой задачи.
qwr

2

Japt , 27 байт

\Ua"" a a a " ÄU\\\"a "aU Ä
            " ÄU\\\"a "     // Given this string literal,
                       aU   // find the last index of the input
                          Ä // and add +1.
\Ua"" a a a                 // Do nothing useful, but make the results match.

Дольше, чем существующий ответ Japt, но использует другой подход.
Имеет врожденное ограничение, что все символы должны встречаться уникальное количество раз.

Принимает ввод в виде строки.

Попробуйте онлайн!


2

Perl, 130 байт

+print+0+((0)x40,6,6,0,3,43,0,0,0,22,12,6,3,5,2,4,0,1,0,0,0,1,0,1,(0)x28,1,0,1,(0)x6,1,(0)x4,1,(0)x4,1,1,1,0,2,0,1,0,0,0,5)[ord<>]

Не имеет новой строки или других пробелов. Читает строку из стандартного вывода, но заботится только о его первых байтах, а затем печатает число раз, которое байт встречается в его собственном исходном коде в десятичном виде, без новой строки.

Программа проста. Большая часть исходного кода занята литеральной таблицей, которая дает ответ для каждого возможного байта. Конечные нули опущены, а соседние нули сжаты во время выполнения, но кроме этого нет особого трюка. Остальная часть программы просто читает входные данные и ищет ответ в таблице.

Например, часть 22, 12, 6, 3, 5, 2, 4, 0, 1, 0в исходном коде дает частоту цифр, поэтому в исходном коде есть 22 нуля, 12 единиц, 6 двойок и т. Д. В результате, если вы введете 0стандартный ввод программы, программа напечатает 22.


2

C (gcc) , 1033 байта

#include <stdio.h>
int main(int argc,char *argv[]){int r=0*14811;switch((int)argv[1][0]){case' ':r=6;break;case'"':r=3;break;case'#':r=2;break;case'%':r=2;break;case'\'':r=101;break;case'(':r=5;break;case')':r=5;break;case'*':r=5*1*1;break;case'.':r=2;break;case':':r=51;break;case';':r=103;break;case'<':r=2;break;case'=':r=52;break;case'>':r=2;break;case'[':r=4;break;case'\\':r=3;break;case']':r=4;break;case'0':r=11;break;case'1':r=20;break;case'2':r=20;break;case'3':r=9;break;case'4':r=7;break;case'5':r=12;break;case'6':r=3;break;case'7':r=2;break;case'8':r=5;break;case'9':r=2;break;case'a':r=106;break;case'b':r=51;break;case'c':r=55;break;case'd':r=4;break;case'e':r=102;break;case'f':r=2;break;case'g':r=4;break;case'h':r=4;break;case'i':r=10;break;case'k':r=51;break;case'l':r=2;break;case'm':r=2;break;case'n':r=8;break;case'o':r=2;break;case'p':r=2;break;case'r':r=108;break;case's':r=53;break;case't':r=8;break;case'u':r=2;break;case'v':r=3;break;case'w':r=2;break;case'{':r=3;break;case'}':r=3;break;}printf("%d",r);}

Попробуйте онлайн!

Это ни в коем случае не является удачным ответом, но было интересно попробовать выполнить эту задачу на языке, с которым я не знаком. Это не было особенно сложной задачей, пока не пришло время найти вхождения цифр, теперь ЭТО было проблемой. Пришлось немного творчески заняться балансировкой :)


2

C (gcc) , 192 байта

F(J){J=J-70?J-40?J-41?J-74?J-'{'?J-'}'?J-39?J-48?J-49?J-50?J-51?J-52?J-53?J-54?J-55?J-56?J-57?J-47?J-61?J-63?J-45?J-58?J-59?0:1:23:23:23:1:2:3:3:4:4:14:14:10:10:15:6:4:2:2:25:1:1:1;}//84332211

Попробуйте онлайн!

Вероятно, возможно, гольф дальше. В конце используется комментарий как «пустое место» для добавления дополнительных цифр. Когда мне нужно сменить цифру с X на Y, я заменяю один из Y на пустом месте на X для компенсации. Кроме этого это просто функция, которая принимает целое число, используя трюк присваивания, чтобы вернуть значение, основанное на большой троичной условной переменной.


Я могу сохранить 1 байт, переместив числовую константу после нуля, как 0*84332211в другом ответе на C, но я также могу сохранить байты, изменив рефакторинг, чтобы он был меньше, поэтому я пока не буду беспокоиться.
LambdaBeta

Можете ли вы сохранить байты, используя проверку диапазона для менее распространенных чисел? то есть, если мы предполагаем, что 4-9 являются редкими символами, мы можем обработать их все одновременно с помощью условной проверки.
QWR

Почти наверняка. Вероятно, мы могли бы удалить еще больше, выбрав умные имена для вещей, чтобы определенные символы никогда не появлялись или чтобы можно было использовать битовые комбинации (например, J&1?чтобы соответствовать всем нечетным символам). Я могу продолжить игру в гольф, если найду время для этого.
LambdaBeta

2

x86 .COM, 17 байт, спорный

0120 BF2001        MOV     DI,0120 (120 be the current address)
0123 B91100        MOV     CX,0011
0126 AE            SCASB
0127 7502          JNZ     012B
0129 FEC4          INC     AH
012B E2F9          LOOP    0126
012D C1E808        SHR     AX,8
0130 C3            RET

36 байт

0100 BF????        MOV     DI,(an copy of this code)
0103 B91200        MOV     CX,0012
0106 AE            SCASB
0107 7503          JNZ     010C
0109 80C402        ADD     AH,02
010C E2F8          LOOP    0106
010E C1E808        SHR     AX,8
0111 C3            RET

2
Разве это не чтение собственного кода?
Разван Соколь

@RazvanSocol Я думаю, что это похоже на решение JavaScript
l4m2

@RazvanSocol ну, это не требует сохранения в файле, так что все в порядке. много грибов и JS тоже делают это
только ASCII

Я утверждаю, что вы читаете исполняемый код, который считается «чтением собственного исходного кода». Теперь можно утверждать, что наличие строковой копии программы, как это делают большинство решений, также «читает исходный код», но строка не выполняется.
14




1

х86, 42 40 байт

Здесь я использую ту же стратегию, что и другие: создайте строковую копию программы с уникальными байтами, а затем верните 2 в al если вход alнаходится в строке. Если мы позволим себе читать код, который на самом деле выполняется, мы получим решение l4m2 .

Я должен использовать классную инструкцию строки scasb . Насколько я знаю, дублирующих байтов не существует, но это то, что я легко испортил. Загрузка строки адреса занимает 5 байт , но я не знаю ни одного короткого решения (64-бит leaиз ripсо смещением занимает 6 байт).

-2, прыгая назад, чтобы избежать использования 02 дважды.

.section .text
.globl main
main:
        mov     $0xff, %eax

start:
        push    $20             # program length
        pop     %ecx            # counter
        mov     $str, %edi      # load string

loop:
        scasb                   # if (al == *(edi++))  
        jne     loop1           
        mov     $2, %al         # ret 2
end:    ret             
loop1:
        loop    loop            # do while (--counter)
        xor     %eax, %eax      # ret 0
        jmp     end

str:    .byte 0x6a,0x14,0x59,0xbf,0xf4,0x83,0x04,0x08 
        .byte 0xae,0x75,0x03,0xb0,0x02,0xc3,0xe2,0xf8
        .byte 0x31,0xc0,0xeb,0xf9 

Hexdump (двоичного формата файла elf32-i386, так как, к сожалению, в файле obj есть 00байты дляstr адреса):

000003e0  6a 14 59 bf f4 83 04 08  ae 75 03 b0 02 c3 e2 f8  |j.Y......u......|
000003f0  31 c0 eb f9 6a 14 59 bf  f4 83 04 08 ae 75 03 b0  |1...j.Y......u..|
00000400  02 c3 e2 f8 31 c0 eb f9                           |....1...|

x86, 256 байт

Скучный ответ, который является эквивалентом гигантского комментария. Ввод cl, немедленно возвращает 1 в al. Я сделаю реальный ответ, когда у меня будет свободное время.

00000039  b0 01 c3 00 02 03 04 05  06 07 08 09 0a 0b 0c 0d  |................|
00000049  0e 0f 10 11 12 13 14 15  16 17 18 19 1a 1b 1c 1d  |................|
00000059  1e 1f 20 21 22 23 24 25  26 27 28 29 2a 2b 2c 2d  |.. !"#$%&'()*+,-|
00000069  2e 2f 30 31 32 33 34 35  36 37 38 39 3a 3b 3c 3d  |./0123456789:;<=|
00000079  3e 3f 40 41 42 43 44 45  46 47 48 49 4a 4b 4c 4d  |>?@ABCDEFGHIJKLM|
00000089  4e 4f 50 51 52 53 54 55  56 57 58 59 5a 5b 5c 5d  |NOPQRSTUVWXYZ[\]|
00000099  5e 5f 60 61 62 63 64 65  66 67 68 69 6a 6b 6c 6d  |^_`abcdefghijklm|
000000a9  6e 6f 70 71 72 73 74 75  76 77 78 79 7a 7b 7c 7d  |nopqrstuvwxyz{|}|
000000b9  7e 7f 80 81 82 83 84 85  86 87 88 89 8a 8b 8c 8d  |~...............|
000000c9  8e 8f 90 91 92 93 94 95  96 97 98 99 9a 9b 9c 9d  |................|
000000d9  9e 9f a0 a1 a2 a3 a4 a5  a6 a7 a8 a9 aa ab ac ad  |................|
000000e9  ae af b1 b2 b3 b4 b5 b6  b7 b8 b9 ba bb bc bd be  |................|
000000f9  bf c0 c1 c2 c4 c5 c6 c7  c8 c9 ca cb cc cd ce cf  |................|
00000109  d0 d1 d2 d3 d4 d5 d6 d7  d8 d9 da db dc dd de df  |................|
00000119  e0 e1 e2 e3 e4 e5 e6 e7  e8 e9 ea eb ec ed ee ef  |................|
00000129  f0 f1 f2 f3 f4 f5 f6 f7  f8 f9 fa fb fc fd fe ff  |................|

1

APL (Dyalog Classic) , 30 байтов

⊢⊢⊢11-11-11-'''''''1''⊢-⍳⍳0'⍳⊢

Попробуйте онлайн!

объяснение

В APL одинарные кавычки в строках экранируются путем удвоения, '''''''1''⊢-⍳⍳0'как и строка'''1'⊢-⍳⍳0 , которые содержат все символы, используемые в программе.

Массивы APL по умолчанию 1-проиндексированы, а функция index-of, что интересно, возвращает 1 + max index если элемент не найден.

Таким образом, используя index-of для строки и входные данные возвращаются

Input    Index    Count
'        1        10
1        4        7
⊢        6        5
-        7        4
⍳        8        3
0        10       1
<other>  11       0

Как видно, 11 - indexдает количество символов в программе. Итак, основной алгоритм

11-'''''''1''⊢-⍳⍳0'⍳⊢

Все остальное - раздутый счет персонажей, позволяющий им хорошо вписаться в слоты.


1

R 135 байтов

Вдохновлен этим ответом Python .

Предыдущие версии были сломаны. Спасибо @Giuseppe за указание на то, что pasteэто не требуется, он сэкономил 18 байтов или около того. lengths(regmatches(z,gregexpr(x,z)))это из этого ответа .

function(x,z=rep(c("afilo2679=:","hmpu15'","nstxz","cgr","e","()",'"',","),c(2:5,7,9,15,16)))sum(lengths(regmatches(z,gregexpr(x,z))))

Попробуйте онлайн!



0

Рубин, 48 байтов

->x{%q[->x{%q[].count(x.chr)*2}].count(x.chr)*2}

%q[str]это более удобный способ написания строкового литерала, чем "str"потому, что он может быть вложен внутрь себя, без экранирования. Поэтому я просто поместил весь код, за исключением копии, внутри, а затем удвоил счет.


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.