This sentence employs two a’s, two c’s, two d’s, twenty-eight e’s, five f’s, three g’s, eight h’s, eleven i’s, three l’s, two m’s, thirteen n’s, nine o’s, two p’s, five r’s, twenty-five s’s, twenty-three t’s, six v’s, ten w’s, two x’s, five y’s, and one z.
Such sentences are called autograms. Your task is to write a program or function that has a similar property: it takes as input a byte, and outputs an integer representing the number of times that byte appears in the program's source code. It should output 0 if its input doesn't appear in its source.
Your program must not read its own source code, directly or indirectly, but instead all the data it needs to give its output must be hard-coded, quine style. Your program must be at least one byte in length.
This is code-golf, so the shortest entry (in bytes) wins. I won't accept an answer, so feel free to compete for the shortest solution in your favourite language.
You are strongly encouraged to include an explanation in your post.
Leaderboards
Below are leaderboards both for overall score and per language:
var QUESTION_ID=162408,OVERRIDE_USER=21034;function answersUrl(e){return"https://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function commentUrl(e,s){return"https://api.stackexchange.com/2.2/answers/"+s.join(";")+"/comments?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+COMMENT_FILTER}function getAnswers(){jQuery.ajax({url:answersUrl(answer_page++),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){answers.push.apply(answers,e.items),answers_hash=[],answer_ids=[],e.items.forEach(function(e){e.comments=[];var s=+e.share_link.match(/\d+/);answer_ids.push(s),answers_hash[s]=e}),e.has_more||(more_answers=!1),comment_page=1,getComments()}})}function getComments(){jQuery.ajax({url:commentUrl(comment_page++,answer_ids),method:"get",dataType:"jsonp",crossDomain:!0,success:function(e){e.items.forEach(function(e){e.owner.user_id===OVERRIDE_USER&&answers_hash[e.post_id].comments.push(e)}),e.has_more?getComments():more_answers?getAnswers():process()}})}function getAuthorName(e){return e.owner.display_name}function process(){var e=[];answers.forEach(function(s){var r=s.body;s.comments.forEach(function(e){OVERRIDE_REG.test(e.body)&&(r="<h1>"+e.body.replace(OVERRIDE_REG,"")+"</h1>")});var a=r.match(SCORE_REG);a&&e.push({user:getAuthorName(s),size:+a[2],language:a[1],link:s.share_link})}),e.sort(function(e,s){var r=e.size,a=s.size;return r-a});var s={},r=1,a=null,n=1;e.forEach(function(e){e.size!=a&&(n=r),a=e.size,++r;var t=jQuery("#answer-template").html();t=t.replace("{{PLACE}}",n+".").replace("{{NAME}}",e.user).replace("{{LANGUAGE}}",e.language).replace("{{SIZE}}",e.size).replace("{{LINK}}",e.link),t=jQuery(t),jQuery("#answers").append(t);var o=e.language;/<a/.test(o)&&(o=jQuery(o).text()),s[o]=s[o]||{lang:e.language,user:e.user,size:e.size,link:e.link}});var t=[];for(var o in s)s.hasOwnProperty(o)&&t.push(s[o]);t.sort(function(e,s){return e.lang>s.lang?1:e.lang<s.lang?-1:0});for(var c=0;c<t.length;++c){var i=jQuery("#language-template").html(),o=t[c];i=i.replace("{{LANGUAGE}}",o.lang).replace("{{NAME}}",o.user).replace("{{SIZE}}",o.size).replace("{{LINK}}",o.link),i=jQuery(i),jQuery("#languages").append(i)}}var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe",COMMENT_FILTER="!)Q2B_A2kjfAiU78X(md6BoYk",answers=[],answers_hash,answer_ids,answer_page=1,more_answers=!0,comment_page;getAnswers();var SCORE_REG=/<h\d>\s*([^\n,]*[^\s,]),.*?(\d+)(?=[^\n\d<>]*(?:<(?:s>[^\n<>]*<\/s>|[^\n<>]+>)[^\n\d<>]*)*<\/h\d>)/,OVERRIDE_REG=/^Override\s*header:\s*/i;
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> <link rel="stylesheet" type="text/css" href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"> <div id="answer-list"> <h2>Leaderboard</h2> <table class="answer-list"> <thead> <tr><td></td><td>Author</td><td>Language</td><td>Size</td></tr></thead> <tbody id="answers"> </tbody> </table> </div><div id="language-list"> <h2>Winners by Language</h2> <table class="language-list"> <thead> <tr><td>Language</td><td>User</td><td>Score</td></tr></thead> <tbody id="languages"> </tbody> </table> </div><table style="display: none"> <tbody id="answer-template"> <tr><td>{{PLACE}}</td><td>{{NAME}}</td><td>{{LANGUAGE}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table> <table style="display: none"> <tbody id="language-template"> <tr><td>{{LANGUAGE}}</td><td>{{NAME}}</td><td>{{SIZE}}</td><td><a href="{{LINK}}">Link</a></td></tr></tbody> </table>
-
5\$\begingroup\$ Sandbox. (It's been in there since 2014!) \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 13:01:55 +00:00Commented Apr 16, 2018 at 13:01
-
\$\begingroup\$ Are functions allowed, or only full programs? \$\endgroup\$Uriel– Uriel2018年04月16日 13:08:01 +00:00Commented Apr 16, 2018 at 13:08
-
1\$\begingroup\$ Note: Answers similar to this one doesn't count as valid anymore. \$\endgroup\$user202729– user2027292018年04月16日 14:13:10 +00:00Commented Apr 16, 2018 at 14:13
-
1\$\begingroup\$ FWIW, the proper quine definition is a bit stronger than I would really like for this challenge. For example, I would be quite happy to see a program that uses all the characters in some contiguous range, and just outputs a 1 if its input is in that range, even though this doesn't have "a section of the program which encodes a different part of the program". For that reason I'd have been willing to allow the retina example, though it would have been disappointing if it had put others off from posting, due to already just being 1 byte. (@user202729) \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 14:31:52 +00:00Commented Apr 16, 2018 at 14:31
-
1\$\begingroup\$ Because of my above comment, I've removed the statement that quine rules apply. (I've kept the part about not reading the source code.) \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 14:44:21 +00:00Commented Apr 16, 2018 at 14:44
31 Answers 31
Octave, 44 bytes
@(x)sum([[39,'(())*,239==@[[]]msuxx']]==x)*2
The result of the function, when using each of the characters in the function as input:
' ( ) * , 2 3 9 = @ [ ] m s u x
2 4 4 2 2 2 2 2 4 2 4 4 2 2 2 4
All other input characters returns a zero.
The fact that I had to escape ' made this a whole lot longer. In order to account for the 4 parentheses, I just had a duplicate in the string. However, duplicating apostrophes takes apostrophes, so this just takes us further from the correct result. Therefore, I had to count the number of apostrophes with its ASCII-value, 39. This of course meant I had to check for the characters 3 and 9 too, making it all a lot longer.
-
2\$\begingroup\$ This is the sort of thing I'm hoping to see more of. (Optimising for the problem, rather than just taking a standard quine and adding code to count the characters.) \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 14:01:51 +00:00Commented Apr 16, 2018 at 14:01
Excel, 84 bytes
=IFERROR(MID("65496331125442343343233",FIND(A1,"""123456789,()=MINORFADEOMEN"),1),0)
Find() will look for the value in cell A1 within the string "123456789,()=MINORFADEOMEN (the """ at the beginning is to escape the character and will evaluate to just ").
Based on the result of Find(), the Mid() function will return the corresponding character from the string of numbers. This string was created through iteration until it stopped changing.
If the character in A1 is not found, Find() returns an error so the IfError() function escapes that to return 0 instead.
The OMEN at the end of the string being searched in the Find() function are duplicate letters so their position will never be returned but they were needed to adjust the character counts. Without them, there was an endless loop of changing counts. The letter arrangement is stylistic choice.
JavaScript (ES6), 70 bytes
Doesn't read the source of the function, but this is quite long. Takes input as a 1-character string.
i=>~(n='\34円=\'in(|)0257?:.>[]Odefx~'.indexOf(i))?'3733544333'[n]||2:0
-
\$\begingroup\$ You can shorten this a bunch by reworking a bit to lower the amount of distinct characters:
i=>'36335633'[i='\36円=\'i|&()25.>[]Odefx~n'.indexOf(i)]||~i&&2(8 bytes saved) \$\endgroup\$Yair Rand– Yair Rand2018年04月19日 19:22:05 +00:00Commented Apr 19, 2018 at 19:22
Retina, 1 byte
This wouldn't be valid if following strictly the quine rules, but the OP explicitely allowed it in a comment.
x
In retina a single-line program counts the occurrences of that regex in the input. This challenge is solved by any single ASCII character except `, ., +, *, ?, [, (, ), ^, $, \ and newline.
C# (Visual C# Compiler), (削除) 88 (削除ここまで) 57 bytes
x=>"\\\"(())==>>??..::3300CCaaiinoossttx".Contains(x)?3:0
Returns 3 if the string contains the passed char, otherwise returns 0. The string contains each character of the code atleast once and exactly the amount required to have the char 3 times in the code.
-31 bytes thanks to Kevin Cruijssen
-
\$\begingroup\$ Nice approach! +1 from me. You can save some bytes by removing the parenthesis around
(a)=>and taking the input as string instead of char so the.ToString()is no longer necessary (anda+""could have been used as well, for code-golf challenges you'll never need.ToString()). Also, since.Containsalready contains ana, you might make the input-variable a different unused character (likexorq) to have 3 for each character instead of 4. EDIT: Never mind the last part, I see"is used 4 times as well now. \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年04月17日 12:00:29 +00:00Commented Apr 17, 2018 at 12:00 -
\$\begingroup\$ @KevinCruijssen Thanks for the advice. But is string valid as input? Considering OP asked for a byte as input? \$\endgroup\$Hyarus– Hyarus2018年04月17日 12:08:01 +00:00Commented Apr 17, 2018 at 12:08
-
\$\begingroup\$ As long as it's a single character string I'm pretty sure it is. Most languages can only input string-values anyway, and some that have characters still choose to input as string (like the Java, JavaScript, and Japt for example. Input and output formats are usually pretty flexible. But you could always ask OP in a comment if you're still doubting. :) \$\endgroup\$Kevin Cruijssen– Kevin Cruijssen2018年04月17日 12:15:32 +00:00Commented Apr 17, 2018 at 12:15
-
1\$\begingroup\$ @KevinCruijssen sounds reasonable. And if we escape one of the " we can even get down to the desired 3 per char \$\endgroup\$Hyarus– Hyarus2018年04月17日 12:27:25 +00:00Commented Apr 17, 2018 at 12:27
-
2\$\begingroup\$ Single character strings as input are fine by me. \$\endgroup\$N. Virgo– N. Virgo2018年04月17日 12:32:07 +00:00Commented Apr 17, 2018 at 12:32
Haskell, 66 bytes
The first two versions are essentially a quine which filters the required characters and then takes the length:
q c=length.filter(==c)$id<>show$"q c=length.filter(==c)$id<>show$"
Try it online or test with all characters! *
Alternative without (<>), 72 bytes
q c=length.filter(==c)$(++)<*>show$"q c=length.filter(==c)$(++)<*>show$"
Try it online or test with all characters!
Non-quine alternative, (削除) 87 (削除ここまで) 86 bytes
Might still be improved, but I'm happy that I got it down to only three different groups.
I like this one the best, even though it counts the most bytes. It's computes the character/byte count by as a sum of 2,3 and 7 (note how some characters are in multiple groups):
u t=sum[fst e|e<-[(2," ()-237<=dflnst|"),(3," ()[\\]`mstu"),(7,"\",ee")],t`elem`snd e]
Try it online or test with all characters!
* imports (<>) because TIO's GHC version is 8.0.2
Python 2, (削除) 54 (削除ここまで) (削除) 52 (削除ここまで) 32 bytes
-20 bytes thanks to ovs
("''+.23cnotu()"*2+'"*'*3).count
-
1\$\begingroup\$ How come you don't have either lambda or input? \$\endgroup\$Stewie Griffin– Stewie Griffin2018年04月16日 19:49:07 +00:00Commented Apr 16, 2018 at 19:49
-
2\$\begingroup\$ @StewieGriffin Python automatically binds a method reference, so
"xxx".countis equivalent tolambda c:"xxx".count(c). \$\endgroup\$Neil– Neil2018年04月17日 00:00:42 +00:00Commented Apr 17, 2018 at 0:00 -
\$\begingroup\$ @StewieGriffin and you use both in the same way ->
f="xxx".countandf=lambda c:"xxx".count(c)will be called asf('a')\$\endgroup\$Rod– Rod2018年04月17日 00:06:59 +00:00Commented Apr 17, 2018 at 0:06
Husk, (削除) 11 10 (削除ここまで) 8 bytes
Thanks Leo for -2 bytes!
#sD"#sD"
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
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\$\begingroup\$ You can manage the quotes more easily by doubling the string before showing it: Try it online! \$\endgroup\$Leo– Leo2018年04月16日 22:27:23 +00:00Commented Apr 16, 2018 at 22:27
Java 10, (削除) 164 (削除ここまで) (削除) 81 (削除ここまで) 57 bytes
q->"q-->>\\\"..ccoonttaaiiss(())??33::00".contains(q)?3:0
Port of @Hyarus' C# answer, so make sure to upvote him!
Explanation:
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
Old quine 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:
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
quine-part:
- The String
scontains the unformatted source code. %sis used to input this String into itself with thes.format(...).%c,%1$cand the34are used to format the double-quotes.s.format(s,34,s)puts it all together
Challenge part:
.replaceAll("[^"+c+']',"")removes all characters except those equal to the input..length()then takes the length of this String.
NOTE: .split(c).length (with String input instead of char) may seem shorter, but has two problems:
- The first character gives an incorrectly result, so if
c(withc->as leading part) is input, it will incorrectly return one character too few. This can be fixed by adding+(c==99?1:0)in both the source code and unformatted source code String (and changing.split(c)to.split(c+""), but then we still have the following problem: - If a regex character (i.e.
$) is input, the.splitwill interpret it as a regex, giving an incorrect result.
Haskell, 58 bytes
f c=sum[2|x<-succ '!':"f c=sum[2|x<-succ '!':,x==c]",x==c]
Try it online! or verify the solution.
Same byte count alternatives:
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 bytes
sum.($zip"1234\",ドル.[\\]opu+()iklmsz652"$[4,4,11,3,3,3,16,5,3,3,3,3,3,3,3]++[2,2..]).lookup
Try it online! or verify the solution. Uses the fact that sum Nothing = 0 and e.g. sum (Just 4) = 4.
Smalltalk, 112 (削除) 132 (削除ここまで) bytes
Smalltalk isn't exactly known for its golfing suitability :-)
Method defined in class Character (tested in VA Smalltalk and Squeak, should work in other dialects such as VisualWorks and Pharo as well):
a^(0to:6),#(10 18)at:(#('' ',[]^|+68cForu' '#0adefln' '1it' '()' ':s' ' ' '''')findFirst:[:s|s includes:self])+1
Characters occurring in the source are grouped by occurrence count. The groups are tested for the first one which contains the receiver, and the matching occurrence count is returned.
Old method:
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\$\begingroup\$ Welcome to PPCG! \$\endgroup\$Martin Ender– Martin Ender2018年04月18日 13:23:47 +00:00Commented Apr 18, 2018 at 13:23
-
1\$\begingroup\$ I think this reads its own source code, doesn't it? That's explicitly banned, in bold, in the question. \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 13:24:40 +00:00Commented Apr 16, 2018 at 13:24
-
1
-
2\$\begingroup\$ Hmm. Well honestly I think that's stupid, but I can't really disagree with meta consensus I suppose. \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 13:26:37 +00:00Commented Apr 16, 2018 at 13:26
-
1\$\begingroup\$ @Nathaniel For all programs that make eval easy, they also make quine easy. \$\endgroup\$user202729– user2027292018年04月16日 13:28:14 +00:00Commented Apr 16, 2018 at 13:28
-
1\$\begingroup\$ @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 \$\endgroup\$N. Virgo– N. Virgo2018年04月16日 13:29:46 +00:00Commented Apr 16, 2018 at 13:29
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
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
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
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.
-
\$\begingroup\$ :| what happened to your spelling in the explanation \$\endgroup\$ASCII-only– ASCII-only2018年04月17日 11:15:42 +00:00Commented Apr 17, 2018 at 11:15
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\$\begingroup\$ This is a great language for this challenge. \$\endgroup\$qwr– qwr2018年04月18日 00:43:59 +00:00Commented Apr 18, 2018 at 0:43
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.
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.
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);}
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 :)
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
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.
-
\$\begingroup\$ I can save 1 byte by moving the numeric constant to after the zero as
0*84332211like 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. \$\endgroup\$LambdaBeta– LambdaBeta2018年04月19日 20:34:10 +00:00Commented Apr 19, 2018 at 20:34 -
\$\begingroup\$ 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. \$\endgroup\$qwr– qwr2018年04月19日 20:37:20 +00:00Commented Apr 19, 2018 at 20:37
-
\$\begingroup\$ 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. \$\endgroup\$LambdaBeta– LambdaBeta2018年04月19日 20:39:27 +00:00Commented Apr 19, 2018 at 20:39
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\$\begingroup\$ Isn't this reading it's own code? \$\endgroup\$Razvan Socol– Razvan Socol2018年04月16日 17:17:23 +00:00Commented Apr 16, 2018 at 17:17
-
\$\begingroup\$ @RazvanSocol I think it's like the JavaScript solution \$\endgroup\$l4m2– l4m22018年04月16日 17:58:34 +00:00Commented Apr 16, 2018 at 17:58
-
\$\begingroup\$ @RazvanSocol well it doesn't require saving in a file so it's okay. a lot of fungeoids and JS also do this \$\endgroup\$ASCII-only– ASCII-only2018年04月17日 11:16:49 +00:00Commented Apr 17, 2018 at 11:16
-
\$\begingroup\$ 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. \$\endgroup\$qwr– qwr2018年04月19日 19:59:31 +00:00Commented Apr 19, 2018 at 19:59
APL (Dyalog Classic), 30 bytes
⊢⊢⊢11-11-11-'''''''1''⊢-⍳⍳0'⍳⊢
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.
Jelly, 16 bytes
";)w8a2";)""w8a2
Every character appears exactly twice.
";)w8a2";)""w8a2
";)w8a2";)"" the string ;)w8a2""
w8a2 return 2 if input in string
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 0ドルxff, %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 |................|
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))))
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.