Challenge

Write a non-empty program/function p that, given a non-empty input string s, outputs the position of the first occurrence of each character of s in the source code of p.

For example, if your program is

main() { cout << magic << cin }
^0   ^5   ^10  ^15  ^20  ^25

and it receives an input abcd{, the output should be

[1, x, 9, x, 7] (0-based)        [2, x, 10, x, 8] (1-based)

Here, x represents any output that is not a valid output for a character position (e.g., a negative number, 0 if you use 1-based indexing, NaN, Inf, the string potato, a number greater than your program's length, etc).

Restrictions

Reading the source code is not allowed (like in a proper quine). The use of comments is allowed, but does count towards your score.

Input and output can be done in a reasonable format, but must be unambiguous (only additional delimiters, no rand stream and claiming that the answer is somewhere in there), consistent (e.g., the x from above should always be the same value) and human-readable; for example, a string or a character array. You can assume that the input is a string (or array) of printable ASCII characters; no need to handle the entire Unicode set.


Custom code-page or non-printable ascii in your code?

If your language uses a custom code-page (Jelly, APL, etc), you must take that into account (so a program €æÆ must output [1, x, 2] for an input €%æ). Using only non-ASCII characters to output -1 always (since the input is ASCII-only) is not a valid solution. You may assume that your program natively accepts your custom codepage, i.e., if your program has a method of converting a character A to an integer 65 (ASCII encoding), you may assume that it now converts the 65th character in your codepage to 65.


Inspired on the following challenge: Positional Awareness

share|improve this question
    
Does capitalisation matter? – Kritixi Lithos 2 days ago
    
@KritixiLithos by default, yes. – Martin Ender 2 days ago
    
@KritixiLithos It does indeed. – Sanchises 2 days ago
    
If my program only uses indices 0 to 9, do I need a separator or could I output, e.g., 01030708070? – Dennis 2 days ago
    
@Dennis No, you do not. It's unambiguous, consistent and human-readable. Requiring a separator would not add anything interesting to the challenge, so by all means abuse your low byte count. ;) – Sanchises 2 days ago

14 Answers 14

Python2, 55 Bytes

a=" )dfi(+m,nprut.';";print map(('a="'+a).find,input())

Starts with a string that contains all the characters used in the code, and then search the indexes

share|improve this answer
3  
I don't see how this is the boring answer. I think using the standard quine is a lot less interesting than this. :) – Martin Ender 2 days ago
    
Since this is Python 2, wouldn't this break on most inputs?. If it does break, you'd have to use raw_input. – TidB 2 days ago
    
@TidB hmm, I guess no? what input do you have in mind? – Rod 2 days ago
    
@Rod Nevermind, I was just being a little dumb. It'll always work when you input an iterable. Silly me. – TidB 2 days ago

Jelly, 10 9 bytes

“ṾiЀƓv”v

Try it online!

How it works

“ṾiЀƓv”v  Main link. No arguments.

“ṾiЀƓv”   Set the left argument and the return value to s := 'ṾiЀƓv'.
        v  Execute the string s as a monadic Jelly program with argument s.

 Ṿ         Uneval; yield a string representation of s, i.e., r := '“ṾiЀƓv”'.
     Ɠ     Read one line from STDIN and evaluate it like Python would.
  iЀ      Find the index of each character in the input in r.
      v    Eval the list of indices as a monadic Jelly program with argument s.
           Why?
             This is the shortest way to add the character 'v' to the string s,
             meaning that we can use r without having to append anything.
           What?
             The v atom vectorizes at depth 1 for its left argument, meaning that
             it acts on arrays of numbers and/or characters. When fed an array of
             integers, it first converts them to strings, then concatenates the
             strings and evaluates them as a Jelly program. For example, the array
             [1, 2, 3] gets cast to the string '123', then evaluates, yielding 123.
             Something slightly different happens if the array starts with a 0. For
             example, the array [0, 1, 2] gets cast to '012' just as before, but
             Jelly views '0' and '12' as two separate tokens; numeric literals
             cannot start with a 0. Since the Jelly program is monadic, the first
             token – '0' – sets the return value to 0. Since the second token –
             '12' – is also a niladic link, the previous return value is printed
             before changing the return value to 12. Then, the program finishes
             and the last return value is printed implicitly.
share|improve this answer

Lenguage, 56,623 bytes

Below is a hexdump of the first 256 bytes. The remaining bytes can be chosen arbitrarily.

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

Output is in bytes, as customary for brainfuck et al.

How it works

This is a simple cat program, specifically ,[.,].

The source code contains all 256 byte values in order, so each byte's index in it matches its value.

share|improve this answer
2  
Hmmm I think Lenguage is the only language where people are outgolfed by three orders of magnitude... – Sanchises yesterday
    
Lenguage is also the only language that constantly finds ways to cheat that wouldn't even be remotely competitive in other languages. :P – Dennis 22 hours ago

CJam, 14 12 bytes

{sq\f#p_~}_~

Uses 0-based indexing and -1 for characters that don't appear in the source.

Try it online!

share|improve this answer

Javascript, 34 bytes

f=a=>a.map(v=>('f='+f).indexOf(v))

It takes input as array of strings, x is -1 (0-based indexing).

share|improve this answer
    
It's allowed, since that method is also acceptable for quines. It doesn't open its source file and read it or use a variable initialized to the source. – mbomb007 yesterday
    
@mbomb007 I can't speak for all JavaScript engines but in Firefox Function.toString works by reading the source. At one point it would crash in debug builds if the source was no longer there when it tried to read it. (I haven't tried it recently because debug builds are so crashy in general.) – Neil yesterday
    
I don't think it's any different than doing s='s=%s;print s%%s';print s%s in Python. It doesn't include the f=, so it's okay – mbomb007 yesterday
1  
You can not really do that, because the input a is supposed to be a string. There is no map function for strings. – manonthemat yesterday
    
@manonthemat "You can assume that the input is a string (or array)" – LarsW yesterday

C, 153 152 143 bytes

char s[99],p[]="odeflnrti%()*+-0;<={}\\";c;f(char*i){sprintf(s,"char s[99],p[]=\"%s",p);for(c=0;c<strlen(i);)printf("%d ",strchr(s,i[c++])-s);}

Try it online!

share|improve this answer

Ruby, 41 88 86 71 69 67 61 bytes

a='p$<.chrsm{| #index};"';p$<.chars.map{|c|"a='#{a}".index c}

Thx Lynn for killing 6 bytes

share|improve this answer
1  
a='p$<.chrsm{| #index};"';p$<.chars.map{|c|"a='#{a}".index c} should work too, taking input from STDIN. – Lynn 2 days ago

><> (Fish) 70 bytes

 #.0+4*a5;!?l|!?f4*b+l1--naolc3*1+0.01?!|~ed+0.0+2e-{:;!?+1:i-1:r}+2:"

Probably the longest ><> 1 liner I've ever made.

It will print the output for each character found on a separate line (0 indexed).

A non found character will always print the length of the code + 1 (I could change this if deemed not okay in it's current state) so in this case 71 will always be the "Not found" characters.

I'll run up an explanation once I get the time.

Some test cases;

##K = 1\n1\n71

#"# = 1\n69\n1

Try it online

><> language

share|improve this answer
    
I think 71 is fine as an output for not found. It's consistent, unambiguous and human-readable, which I think is more important than it being "...any output that is not a positive integer". I expanded the rules to reflect this decision. – Sanchises 2 days ago
    
@Sanchises Thank you :) – Teal pelican yesterday

Lenguage, 1.22e7 bytes

Consists of 12263215 NUL bytes, (Hex 0x00).

Outputs a NUL for every character that doesn't appear in the source.

The ruse is that the input will never contain a NUL, so we always output the amount of NULs that there are characters in the input.

This translates to the following Brainfuck program

,[[-].,]

And with a breakdown...

,[[-].,]
,[    ,]    #Basic Input loop.
  [-]       #Zero out the cell.
     .      #Print it (A NUL).

This just shows the sheer power of Lenguage as a golfing language. Fear it.

share|improve this answer
1  
Such a clever ruse, you almost won... Did you try the reverse too, I.e 0x00 bytes and 1-indexing? – Sanchises yesterday
    
I would have loved to, but Brainfuck/Lenguage (Or atleast, the interpreter I'm using) cannot differentiate between EOF and 0x00, So I would be unable to actually answer the challenge. – ATaco yesterday
    
Brainfuck et al. are usually allowed to print integers as bytes, i.e., you'd print SOH for 1, NUL for 0. – Dennis yesterday
    
@Sanchises Could you confirm that is the case here? – Dennis yesterday
    
It's not about output in this case, Input is the issue. – ATaco yesterday

Perl 6, 50 52 bytes

{(('R~.index$_) for}\\'R~'{((\'').index($_) for $_)}

Translation of G B's Ruby solution and Rod's Python solution.

A lambda that inputs a list of characters and outputs a list of zero-based indexes (Nil for nonexistent characters).

EDIT: Fixed an oversight - required adding 2 bytes :(

share|improve this answer

Stacked, noncompeting, 36 bytes

When I said this language was still in development, I meant it. Apparently, prompt used to consume the entire stack. This is why I can't have nice things. Try it here!

[tostr ':!' + prompt CS index out]:!

This is the standard quine framework. Basically, : duplicates the function [...] on the stack, which is then executed with !. Then, the inside of [...] executes with the function on the stack. It casts it to a string, appends :! (the program itself), then takes a string input with prompt. CS converts it to a character string. A character string is a bit different from a regular string in that it has operators vectorize over it. In this case, index vectorizes over the input, yielding each index of the input string in the program, finally being outputted.

For input Hello, World!, this gives:

(-1 27 -1 -1 2 -1 6 -1 2 5 -1 26 9)

I tried using the one without a quine (i.e. encoding the string of characters that appear in your source), but there is only one type of quotation mark in Stacked, namely, ', so it would be longer to do that type of solution.

share|improve this answer

Clojure, 43 56 bytes

Edit: Damn I forgot about 2! Increased from 43 to 56.

{\{ 0\\   1\  3\0   4\1 10\4 20\3 14 \} 42}

The hash-map consists only of characters 01234{\\}, and it encodes their locations. In Clojure hash-maps can be used functions, as shown in this complete example (f could be replaced by the hash-map definition):

; Keeping track of the zero-based index:
;      00000000001111111111222222222233333333334444444444
;      01234567890123456789012345678901234567890123456789
(def f {\{ 0\\   1\  3\0   4\1 10\3 14\4 20\2 34 \} 43})

(map f "0123456789{} \\abcdef") ; (4 10 34 14 20 nil nil nil nil nil 0 43 3 1 nil nil nil nil nil nil)
(apply str (keys f))            ; " 01234{\\}"

I guess this counts :)

share|improve this answer

Python, 90 88 bytes

a,b,d=" ()+.7:[]efilmnor","a,b,d=\"",lambda e:[[b.find(d),a.find(d)+7][d in a]for d in e]

Test case:

print(d("a,b(]q"))
#[0, 1, 2, 8, 15, -1]
share|improve this answer

Pyth, 11 bytes

xL_+N"N+_Lx

A program that takes input of a "quoted string", with any quotes in the string escaped with a preceding \, and prints a list of zero-indexed values with -1 for characters not in the source.

Try it online!

How it works

xL_+N"N+_Lx    Program. Input: Q
xL_+N"N+_Lx"Q  Implicit quote closure and implicit input
     "N+_Lx"   Yield the string "N+_Lx"
   +N          Prepend a quote
  _            Reverse
 L          Q  Map over Q:
x               Yield the index of the character in the string
               Implicitly print
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.