Programy autogramów


34

W tym zdaniu stosuje się dwa a, dwa c, dwa d, dwadzieścia osiem e, pięć f, trzy g, osiem h, jedenaście i, trzy l, dwa m, trzynaście n, dziewięć o, dwa p, pięć r, dwadzieścia pięć s, dwadzieścia trzy t, sześć v, dziesięć w, dwa x, pięć y i jeden z.

Takie zdania nazywane są autogramami . Twoim zadaniem jest napisanie programu lub funkcji, która ma podobną właściwość: pobiera jako dane wejściowe bajt i wypisuje liczbę całkowitą reprezentującą liczbę wystąpień bajtu w kodzie źródłowym programu. Powinien wypisać 0, jeśli jego wejście nie pojawi się w źródle.

Twój program nie może odczytywać własnego kodu źródłowego , bezpośrednio lub pośrednio, ale wszystkie dane, które musi przekazać, muszą być zakodowane na sztywno, w stylu quine. Twój program musi mieć co najmniej jeden bajt.

To jest , więc wygrywa najkrótszy wpis (w bajtach). Nie przyjmuję odpowiedzi, więc możesz konkurować o najkrótsze rozwiązanie w swoim ulubionym języku.

Zachęcamy do zamieszczenia wyjaśnienia w swoim poście.

Liderów

Poniżej znajdują się tabele wyników zarówno dla ogólnego wyniku, jak i dla każdego języka:


5
Piaskownica . (Jest tam od 2014 roku!)
Nathaniel

Czy funkcje są dozwolone, czy tylko pełne programy?
Uriel

1
Uwaga: odpowiedzi podobne do tej nie są już uważane za prawidłowe.
user202729,

1
FWIW, właściwa definicja quine jest nieco silniejsza, niż naprawdę chciałbym w przypadku tego wyzwania. Na przykład byłbym bardzo szczęśliwy, widząc program, który używa wszystkich znaków w pewnym ciągłym zakresie, i po prostu wypisuje 1, jeśli jego dane wejściowe znajdują się w tym zakresie, nawet jeśli nie ma „części programu, która koduje inna część programu ". Z tego powodu byłbym skłonny pozwolić na przykład siatkówki, choć byłoby rozczarowujące, gdyby zniechęcił innych do publikowania, ponieważ jest już tylko 1 bajtem. (@ user202729)
Nathaniel

1
Z powodu mojego powyższego komentarza usunąłem stwierdzenie, że obowiązują zasady quine. (Zachowałem część, że nie czytam kodu źródłowego.)
Nathaniel

Odpowiedzi:


15

Oktawa , 44 bajty

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

Wypróbuj online!

Wynik działania, gdy używasz każdego ze znaków w funkcji jako danych wejściowych:

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

Wszystkie pozostałe znaki wejściowe zwracają zero.

Fakt, że musiałem uciec, 'wydłużył to wszystko. Aby uwzględnić 4 nawiasy, właśnie miałem duplikat w ciągu. Jednak powielanie apostrofów wymaga apostrofów, więc to prowadzi nas dalej od prawidłowego wyniku. Dlatego musiałem policzyć apostrofy z jego wartości ASCII, 39. To oczywiście oznaczało, że musieliśmy to sprawdzić dla znaków 3i 9też, co to wszystko o wiele dłużej.


2
To jest coś, co mam nadzieję zobaczyć więcej. (Optymalizacja pod kątem problemu, a nie tylko wzięcie standardowego quinu i dodanie kodu do liczenia znaków.)
Nathaniel

7

Excel, 84 bajty

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

Find()wyszuka wartość w komórce A1w ciągu znaków "123456789,()=MINORFADEOMEN( """na początku jest to znak ucieczki i to po prostu ").

Na podstawie wyniku Find()The Mid()funkcja zwróci odpowiedni znak z ciągiem liczb. Ten ciąg został utworzony przez iterację, aż przestał się zmieniać.

Jeśli znak w A1nie zostanie znaleziony, Find()zwraca błąd, więc IfError()funkcja ucieka przed zwrotem 0.

Na OMENkońcu przeszukiwanego ciągu w Find()funkcji znajdują się zduplikowane litery, więc ich pozycja nigdy nie zostanie zwrócona, ale były potrzebne do dostosowania liczby znaków. Bez nich istniała niekończąca się pętla zmieniających się liczb. Układ liter jest wyborem stylistycznym.


5

JavaScript (ES6), 70 bajtów

Nie odczytuje źródła funkcji, ale jest to dość długie. Pobiera dane wejściowe jako ciąg 1 znaków.

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

Wypróbuj online!


Możesz to skrócić, przerabiając nieco, aby zmniejszyć liczbę różnych znaków: i=>'36335633'[i='\\36=\'i|&()25.>[]Odefx~n'.indexOf(i)]||~i&&2(zapisano 8 bajtów)
Yair Rand

5

Siatkówka , 1 bajt

Nie byłoby to ważne, gdyby ściśle przestrzegał zasad quine, ale OP wyraźnie zezwoliło na to w komentarzu .

x

Wypróbuj online!

W siatkówce program jednowierszowy zlicza wystąpienia tego wyrażenia regularnego na wejściu. Wyzwanie to jest rozwiązane przez dowolny pojedynczy znak ASCII z wyjątkiem `, ., +, *, ?, [, (, ), ^,$ , \i linią.


5

C # (kompilator Visual C #) , 88 57 bajtów

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

Wypróbuj online!

Zwraca 3, jeśli ciąg zawiera przekazany znak, w przeciwnym razie zwraca 0. Łańcuch zawiera co najmniej jeden znak kodu co najmniej dokładnie tyle, ile potrzeba, aby znak miał 3 razy w kodzie.

-31 bajtów dzięki Kevin Cruijssen


Niezłe podejście! +1 ode mnie Możesz zaoszczędzić kilka bajtów, usuwając nawias wokół (a)=>i przyjmując dane wejściowe jako ciąg zamiast znaku, aby .ToString()nie było już konieczne (i a+""mogło być również użyte, do wyzwań związanych z golfem, których nigdy nie będziesz potrzebować .ToString()). Ponadto, ponieważ .Containszawiera już azmienną wejściową, możesz zmienić zmienną wejściową na inny nieużywany znak (jak xlub q), aby mieć 3 dla każdego znaku zamiast 4. EDYCJA: Nieważne, że ostatnia część, widzę, że "jest teraz używana 4 razy.
Kevin Cruijssen

@KevinCruijssen Dzięki za radę. Ale czy ciąg jest ważny jako dane wejściowe? Biorąc pod uwagę, że OP poprosił o bajt jako dane wejściowe?
Hyarus

Tak długo, jak długo jest to ciąg znaków, jestem pewien, że tak. Większość języków i tak może wprowadzać tylko wartości ciągu, a niektóre, które mają znaki, nadal wybierają ciąg znaków (na przykład Java, JavaScript i Japt. Formaty wejściowe i wyjściowe są zazwyczaj dość elastyczne. Ale zawsze możesz poprosić OP w skomentuj, jeśli nadal masz wątpliwości. :)
Kevin Cruijssen

1
@KevinCruijssen brzmi rozsądnie. A jeśli uda nam się uciec od jednego z „możemy nawet dostać się do pożądanej 3 na char
Hyarus

2
Ciągi pojedynczych znaków jako dane wejściowe są dla mnie w porządku.
Nataniel

4

Haskell , 66 bajtów

Pierwsze dwie wersje to w zasadzie quine, które filtruje wymagane znaki, a następnie przyjmuje długość:

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

Wypróbuj online lub przetestuj ze wszystkimi postaciami! *


Alternatywnie bez (<>)72 bajtów

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

Wypróbuj online lub przetestuj ze wszystkimi postaciami!


Alternatywna wersja quine, 87 86 bajtów

Może być jeszcze ulepszony, ale cieszę się, że udało mi się go ograniczyć tylko do trzech różnych grup.

Ten najbardziej mi się podoba, mimo że liczy najwięcej bajtów. Oblicza liczbę znaków / bajtów jako sumę 2,3 i 7 (zwróć uwagę na to, jak niektóre znaki są w wielu grupach):

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

Wypróbuj online lub przetestuj ze wszystkimi postaciami!


* importuje, (<>)ponieważ wersja GHC TIO to 8.0.2


3

Python 2 , 54 52 32 bajty

-20 bajtów dzięki ovs

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

Wypróbuj online!


1
How come you don't have either lambda or input?
Stewie Griffin

2
@StewieGriffin Python automatically binds a method reference, so "xxx".count is equivalent to lambda c:"xxx".count(c).
Neil

@StewieGriffin and you use both in the same way ->f="xxx".count and f=lambda c:"xxx".count(c) will be called as f('a')
Rod

3

Husk, 11 10 8 bytes

Thanks Leo for -2 bytes!

#sD"#sD"

Try it online!

Explanation

This makes sure that it only uses ASCII (because show would mess it up) and that each character is contained twice:

#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

Standard quine extension, 11 bytes

#hS+s"#hS+s

Try it online!

Explanation

#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
Możesz łatwiej zarządzać cytatami, podwajając ciąg przed wyświetleniem: Wypróbuj online!
Leo

3

Java 10, 164 81 57 bytes

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

Port @Hyarus' C# answer, so make sure to upvote him!

Explanation:

Wypróbuj online.

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

Stary 164-bytes answer:

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();}

Explanation:

Wypróbuj online.

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

-part:

  • The String s contains the unformatted source code.
  • %s służy do wprowadzania tego ciągu do siebie za pomocą s.format(...) .
  • %c, %1$cA34 służą do formatowania podwójnych cudzysłowów.
  • s.format(s,34,s) łączy to wszystko

Część wyzwania:

  • .replaceAll("[^"+c+']',"") usuwa wszystkie znaki oprócz tych równych wejściowi.
  • .length() następnie przyjmuje długość tego ciągu.

UWAGA: .split(c).length(z Stringwejściem zamiastchar ) może wydawać się krótszy, ale ma dwa problemy:

  1. Pierwszy znak podaje niepoprawny wynik, więc jeśli c( c->jako część wiodącą) zostanie wprowadzony, zwróci niepoprawnie jeden znak za mało. Można to naprawić, dodając +(c==99?1:0)zarówno kod źródłowy, jak i niesformatowany ciąg kodu źródłowego (i zmieniając .split(c)na .split(c+""), ale nadal mamy następujący problem:
  2. Jeśli zostanie wprowadzony znak wyrażenia regularnego (tj. $), .splitZinterpretuje go jako wyrażenie regularne, dając niepoprawny wynik.

3

Haskell , 58 bajtów

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

Wypróbuj online! lub sprawdź rozwiązanie .

Te same alternatywy dla liczby bajtów:

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 bajtów

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

Wypróbuj online! lub sprawdź rozwiązanie . Wykorzystuje fakt, że sum Nothing = 0i np sum (Just 4) = 4.


3

Smalltalk , 112 132 bytes

Smalltalk nie jest dokładnie znany ze swojej przydatności do gry w golfa :-)

Metoda zdefiniowana w klasie Character (przetestowana w VA Smalltalk i Squeak, powinna również działać w innych dialektach, takich jak VisualWorks i Pharo):

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

Znaki występujące w źródle są pogrupowane według liczby wystąpień. Grupy są testowane pod kątem pierwszej, która zawiera odbiornik, i zwracana jest liczba zgodnych wystąpień.

Stara metoda:

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

Every character that does appear in the method appears exactly 6 times (by being repeated in the string constant), so the method just checks whether the receiver is contained in the string and returns 6 if it is, 0 otherwise.

After defining the method as above, you can validate it using

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

The result should be empty.


1
Welcome to PPCG!
Martin Ender

2

JavaScript, 31 bytes

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

Try it online


1
I think this reads its own source code, doesn't it? That's explicitly banned, in bold, in the question.
Nathaniel

1
@Nathaniel, see here.
Shaggy

2
Hmm. Well honestly I think that's stupid, but I can't really disagree with meta consensus I suppose.
Nathaniel

1
@Nathaniel For all programs that make eval easy, they also make quine easy.
user202729

1
@user202729 I don't think that follows, does it? You can't do the same trick in Python, for example. This is a reverse eval, not an eval
Nathaniel



2

Haskell, 96 bytes

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

Try it online!

Haskell, 109 bytes

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

Try it online!

Haskell, 122 bytes

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

Try it online!

Explanations

These answers are not terribly sophisticated. It is a series of declarations, one for each character present in the program. At the end we have a catch all that returns 0 for characters not present in the program.

I use a couple of tricks to minimize the number of characters necessary in the program and from there I fiddled with things until the numbers turned out just right. You can see that I've padded the variable name in the last declaration, in all 3 of them. The difference between the 3 programs is whether I chose to use a new line or ; for line breaks and whether I chose to take Chars as input or Strings. The ; approach doesn't seem inherently superior to the others it just gets luck and ends up shorter, however it does seem that using Strings is a better idea than Chars because Chars require spaces after the function name an Strings do not.


:| what happened to your spelling in the explanation
ASCII-only

2

Whitespace, 140 bytes

[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]

Letters S (space), T (tab), and N (new-line) added as highlighting only.
[..._some_action] added as explanation only.

70 spaces, 37 tabs, and 33 new-lines used.

Usually I use the Create Labels in the order NSSN, NSSSN, NSSTN, NSSSSN, NSSSTN, NSSTSN, NSSTTN, etc. But because printing a number where the binary S=0/T=1 is used affects the number I need to output, I used the labels NSSN, NSSSN, NSSTN, and NSSSTN instead, which gave the perfect amount of spaces/tabs to be printed with the binary numbers SSSTSSSSTN (33; amount of new-lines), SSSTSSTSTN (37; amount of tabs), and SSSTSSSTTSN (70; amount of spaces).

Explanation in pseudo-code:

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

Example runs:

Input: space

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

Program stops with an error: No exit defined.
Try it online (with raw spaces, tabs, and new-lines only).

Input: tab

STDIN will be \t (9) instead, in which case it will be 0 at the first If 0 check, goes to LABEL_TAB/NSSSTN, and will push and print 37 instead.

Try it online (with raw spaces, tabs, and new-lines only).

Input: new-line

STDIN will be \n (10) instead, in which case it will be 0 at the second If 0 check, goes to Label_NEWLINE/NSSSN, and will push and print 33 instead.

Try it online (with raw spaces, tabs, and new-lines only).

Input: anything else

Any other input-character will do NSTN (Jump to Label_PRINT) after the third If 0 check, printing the 0 that was still on the stack (which we've duplicated at the very beginning).

Try it online (with raw spaces, tabs, and new-lines only).


1
This is a great language for this challenge.
qwr

2

Japt, 27 bytes

\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.

Longer than the existing Japt answer, but uses a different approach.
Has the inherent limitation that all chars need to occur a unique number of times.

Takes input as a string.

Try it online!


2

Perl, 130 bytes

+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<>]

Has no newline or other whitespace. Reads a line from the standard output, but only cares about its first bytes, then prints the number of times that byte occurs in its own source code in decimal, without a newline.

The program is straightforward. Most of the source code is occupied by a literal table that gives the answer for the each possible byte. Trailing zeros are omitted, and adjacent zeros are run-time compressed, but there's no special trick other than that. The rest of the program simply reads the input and looks up the answer in the table.

For example, the part 22, 12, 6, 3, 5, 2, 4, 0, 1, 0 in the source code gives the frequency of digits, so there are 22 zeroes, 12 ones, 6 twos etc in the source code. As a result, if you enter 0 to the standard input of the program, the program will print 22.


2

C (gcc), 1033 bytes

#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);}

Try it online!

This is by NO means a golfed answer, but it was fun to try to accomplish this challenge in a language which I am not familiar with. It wasn't a particularly difficult challenge until it came time to find the occurrences of the digits, now THAT was a challenge. Had to do a little creative balancing :)


2

C (gcc), 192 bytes

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

Try it online!

Probably possible to golf down further. Uses a comment at the end as a 'scratch space' to add extra digits. When I have to change a digit from X to Y, I change one of the Y's in the scratch to an X to compensate. Other than that this is just a function that takes an integer, using the assignment trick to return a value based on a large ternary conditional.


I can save 1 byte by moving the numeric constant to after the zero as 0*84332211 like in the other C answer, but I can also save bytes by refactoring that to be smaller, so I'm not going to bother just yet.
LambdaBeta

Can you save bytes by using a range check for the less common numbers? that is if we assme 4-9 are rare characters, we can handle them all at once with a conditional check.
qwr

Almost certainly. We could probably remove even more by picking clever names for things so that certain symbols never appear or so that the bit-patterns can be used (e.g. J&1? to match all odd characters). I may further golf this if I find the time to do so.
LambdaBeta

2

x86 .COM, 17 bytes, controversial

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 bytes

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
Isn't this reading it's own code?
Razvan Socol

@RazvanSocol I think it's like the JavaScript solution
l4m2

@RazvanSocol well it doesn't require saving in a file so it's okay. a lot of fungeoids and JS also do this
ASCII-only

I argue you are reading code that is executed, which counts as "reading own source code". Now you could argue having a string copy of the program, as most solutions here do, is also "reading source code", but the string isn't executed.
qwr

1

Japt, 14 bytes

Qi"QiUè² " ²èU

Try it


Explanation

                   :Implicit input of character string U
  "QiUè² "         :String literal
Qi                 :Append a quotation mark
           ²       :Repeat twice
            èU     :Count the occurrences of U


1

Jelly, 16 bytes

“;⁾w⁸a2”;⁾“”w⁸a2

Try it online!

Every character appears exactly twice.

“;⁾w⁸a2”;⁾“”w⁸a2
“;⁾w⁸a2”;⁾“”     the string ;⁾w⁸a2“”
            w⁸a2 return 2 if input in string

1

x86, 42 40 bytes

Here I use the same strategy as others: Create a string copy of the program with unique bytes, then return 2 in al if the input al is in the string. If we allow ourselves to read code that is actually run, we get l4m2's solution.

I got to make use of a cool string instruction scasb. To the best of my knowledge, there are no duplicate bytes, but this is something I'd easily screw up. Loading the string address takes 5 bytes but I'm not aware of any shorter solution (64-bit lea of rip with offset takes 6 bytes).

-2 by jumping backwards to avoid using 02 twice.

.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 (of binary file format elf32-i386, as obj file unfortunately has 00 bytes for str address):

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 bytes

Boring answer that is the equivalent of a giant comment. Input in cl, immediately returns 1 in al. I'll make an actual answer when I have the free time.

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 bytes

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

Try it online!

Explanation

In APL, single quotes within strings are escaped by doubling, so '''''''1''⊢-⍳⍳0' is the string '''1'⊢-⍳⍳0, which contain every character used in the program.

APL arrays are by default 1-indexed, and the index-of function, interestingly, returns 1 + max index if the element is not found.

So, by using index-of on the string and the input returns

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

As one can see, 11 - index gives the count of the character in the program. So, the basic algorithm is

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

The rest is bloating the character counts to allow them to fit nicely into the slots.


1

R, 135 bytes

Inspired by this Python answer.

Previous versions were broken. Thanks to @Giuseppe for pointing out that paste was not required it saved 18 bytes or so. lengths(regmatches(z,gregexpr(x,z)))is from this answer.

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

Try it online!



0

Ruby, 48 bytes

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

%q[str] is a more convenient way to write a string literal than "str" because it can be nested inside itself without any escaping. So I just put the entire code except for the copy inside it, then double the count.


Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.