\$\begingroup\$Why the limitation of zero not being even? That seems rather odd.\$\endgroup\$
– IsziDec 20 '13 at 16:56

3

\$\begingroup\$Your input requirements really make no sense: For most systems, input comes from stdin, whether prompted by the program or no. Whether or not the input is piped in or not is not under control of the program. -- If your aim was to have users create an interactive program, then you should have been precise about the input and output (including formatting), and the interaction required.\$\endgroup\$
– MtnViewMarkDec 21 '13 at 4:11

Golfscript, 26 (28) characters

'#{gets}' is an escape to ruby to satisfy the I/O requirements; STDIN is assumed to be empty

. clones the input

'246'&8+ finds which even digits are present in the input, except 8 is always retained

$1< sorts the list, then takes the first digit, but keeps it as a string

.@\? orders the stack {digit, input, digit}, then finds the digit in the input; thanks @peterTaylor for noticing me of the [array, array] signature of ?.

I've been very bold with the spec interpretation this time; namely:

The spec does not mandate in which order the integers are output; Use the other @peter's suggestion :x?x to fix (I don't like temporary variables.

The spec does not require any delimiter between the two integers; since the digit found is always a single digit, this does not matter much. If it does, append n@ (which also performs the swap), n\ (which doesn't), or ]` (which formats the output as ["8" -1]).

\$\begingroup\$Also, the spec requires the index to be first, but I can't read GolfScript well enough to tell if you didn't\$\endgroup\$
– user8777Dec 20 '13 at 8:28

\$\begingroup\$@LegoStormtroopr the only point of the spec that mentions the order is #4: "If there is no even digit, return -1 as the index, the second number can be anything". #3 does not specify the order; what about the "no delimiter" boldness?\$\endgroup\$
– John DvorakDec 20 '13 at 8:30

\$\begingroup\$Oh snap, you are correct sir! I mentioned the two numbers to output, but not the order. I stand corrected!\$\endgroup\$
– user8777Dec 20 '13 at 8:32

\$\begingroup\$You can replace .0=@? with .@\? or :x?x to save one character and avoid the doubt over the order. Nice use of 8 as a fallback.\$\endgroup\$
– Peter TaylorDec 20 '13 at 9:38

\$\begingroup\$@SimonT ` (backticks) are not just quotes. It is a deprecated alias for repr() in python 2. But its no longer available in Python 3. So, If I wanna use `` on something in python 3, i have to write repr(something) which cost 4 more chars. Thats why i get rid of it ;)\$\endgroup\$
– WasiDec 27 '13 at 8:30

perl - -94- 53 chars (or 48)

Instead of index()'s zero-based approach we use pos and start at one; no CPAN. Run this with perl -nE and it will wait for input (which it can also receive from STDIN).

The first match (//) operation works on the default value ($_) from input, matching against the given even numbers, sorting the matches into an array, and then storing them in a "scalar list" ($m). In scalar context the list value of the sorted array is one item long and thus consists of the lowest matched even digit in the number.

Having isolated the lowest even matched digit, we then use $m for a second match operation which will find the first occurrence of the value of $m in the original string. We are still using the default value here $_ and we are saving the match against the contents of $m in $1 (the reason for the () around $m in the second statement). After that, pos and say do the rest (and in fewer characters than index and print).

If output order or commas don't matter then it's possible to make this 5 chars shorter:

($m)=sort/[2468]/g;/($m)/g;$1?say$1.pos:say"-10"

In my earlier attempt I rushed and made an error - I just wanted to beat python and ruby (but failed) ... sigh.

Congrats to the winner and the other participants on their cool solutions - especially to perl6 :-) A possible Perl6 adaptation of this approach could use ".comb (suggested on freenode by Masak et.al.).

\$\begingroup\$Was so focused on beating python/ruby that I posted a one liner that did not work when no even numbers were present: eagerly using an earlier version of the above from my $SHELL history for the "win". This working version is ridiculously long and embarrassing. Serves me right: will shorten later to avoid shame :-(\$\endgroup\$
– G. CitoApr 17 '14 at 2:08

Perl 6, 375560 characters

$_=get;say m/<{~.comb(/<[2468]>/).min}>/.from//-1,',',$/.Int

EDIT: I misunderstood the question the first time. This update should be correct. It finds the lowest number of 2,4,6, or 8 that the input contains, and then does a regex match against the input with that lowest number. $/.from gets the position of the match and ',', $/.Int is a comma plus the match itself, or 0 if the text didn't match.

While you're here, go upvote G. Cito, who helped me fix my entry in the comments and on irc :)

\$\begingroup\$Unfortunately this prints first even number (2468) found and not the lowest :( NB. Also there is an issue with $/.from when nothing is found (this maybe a bug in my old version of Rakudo). Here's a variation of your solution which works (for me!) my$x=get;for 2,4,6,8 ->$n{if $x~~/$n/ {say $/.from,",$/";exit}};say "-1 0"; Comes in at 75 chars but I'm sure a shorter perl6 solution can be made.\$\endgroup\$
– draegtunApr 17 '14 at 13:35

\$\begingroup\$@draegtun ... I made a similar error with my perl5 attempt yesterday (see below). My fix added 70 chars! Just updated it with a ~50 char version - which seems to work. I think if you sort all the even digits in the number you can then do a match using the (now) first digit in the sort and be sure you have the lowest and the first. Am I right?\$\endgroup\$
– G. CitoApr 17 '14 at 18:23

\$\begingroup\$@G.Cito Looks good to me and have already +1 your answer. I can see way to shave off a few chars but I see Heiko as done even better than what I was going to suggest!\$\endgroup\$
– draegtunApr 17 '14 at 19:04

\$\begingroup\$@mouq Here's an approach one that uses the same approach as the perl5 example I posted below: my $n; $_="333992";$n=.comb(/<[2468]>/).min;/$n/;say $/.from//-1,",$/". I learned about .comb about 20 minutes ago and I already like it :-)\$\endgroup\$
– G. CitoApr 17 '14 at 22:30

echo ... i=.1!:1]1 is input/output. Way longer than I want it to. Input is stashed away into i as well.

'2468'i.~ finds the first occurence of each even digit in the input, returning the input length if the digit cannot be found

(#~(#i)&>) reads "select by the length of input being greater than this"; in other words, select those indices that point into the input. Way longer than I want it to.

_1,~ appends -1 to the back. Underscore is the J's way of representing negative values.

{. selects the first element

(;{&i) concatenates it with the input character at that position in two boxes; since we're concatenating a number with a character, non-boxing concatenation (,) won't do. If unboxed display is desired, the index needs to be formatted (":) first at a cost of two chars.

\$\begingroup\$k==c?std::cout<<(...),throw 0:0; - the conditional operator can replace if, when all you need are expressions. throw is an expression and also one character shorter than return.\$\endgroup\$
– MSaltersJan 3 '14 at 14:04

$(...) Everything between the parenthesis will be treated as a commands, and the output of that code will be included instead of the commands themselves.

[array]::IndexOf(...) This is used to get the index of an element with the array. Its first parameter is the array object to be searched. The second parameter is the object to be found. This only outputs the index of the first matching element. I tried simply using an IndexOf method directly against $s (e.g.: $s.IndexOf($x), but this fails for some reason I've yet to figure out - it claims the method doesn't exist on that object.

(...) Expression within the parenthesis will be the first parameter for IndexOf.

$s= $s will be a variable to store the user input.

(read-host)-split'' Gets user input, and splits it into an array of characters.`

|?{$_} Filters out extra empty array elements that are generated by -split''.

,(...) Expression within the parenthesis will be the second parameter for IndexOf.

$x= $s will be a variable to store the lowest even digit from the user input.

$s|?{$_%2-eq0} Pulls out the even numbers from $s.

|?{$_-gt0} Invalidates zero.

|sort Sorts the remaining objects, default order is ascending.

|select -f 1 Picks the first object, which will by now be the lowest even digit.

,$x The above code will output the index of our lowest even digit. This adds a comma, and then outputs the digit itself.

Notes:

This is perhaps stretching rule #4 a little bit. If there is no even digit, the output will not include a second number.

Also, this will throw some non-terminating errors if the input includes non-numeric elements. The script will still run and give proper output, but you might want to set $ErrorActionPreference to 'SilentlyContinue' before running it.

\$\begingroup\$@DankoDurbić Now that you've soundly defeated me, would you mind helping me figure out why I couldn't use $s.IndexOf here? It was giving me an error saying the method didn't exist for that object, even though $s|gm said it did. It works on the system I'm on now, but not the one I was trying to do it on earlier today. Is it a version compatibility issue? Earlier system was PSv2, current is PSv4.\$\endgroup\$
– IsziDec 21 '13 at 10:13

\$\begingroup\$Your $s is string[], and $s.indexof doesn't work because ...[System.String[]] doesn't contain a method named 'indexOf', which seems reasonable (I'm running PS 2.0). $s|gm returns members of System.String, not System.String[]. I'm not sure why it does that.\$\endgroup\$
– Danko DurbićDec 21 '13 at 11:02

Bourne shell (sh), 88 chars

I thought I'd do a string-processing thing for fun. Technically it reads from stdin, but if you run it interactively it'll prompt the user for input since the keyboard is the default stdin stream. Uses basic shell commands to split up the input on lines, number them (using the ill-known nl utility), filter out lines fitting the criteria, sort them and output the lowest-digit one. Prints 88 -1 if no even digit was found.

JavaScript - 53 Characters

for(y=prompt(x=0);x<8&&(i=y.indexOf(x+=2))<0;);x+''+i

Reads input from prompt and outputs (to the console) the lowest even character then (without a delimiter) the first index of that character; if there are no non-zero even characters then it outputs 8-1.

Your Answer

If this is an answer to a challenge…

…Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.

…Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
Explanations of your answer make it more interesting to read and are very much encouraged.

…Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.

More generally…

…Please make sure to answer the question and provide sufficient detail.

…Avoid asking for help, clarification or responding to other answers (use comments instead).

Post as a guest

Post as a guest

Code Golf Stack Exchange is a site for recreational programming competitions, not general programming questions. Challenges must have an objective scoring criterion, and it is highly recommended to first post proposed challenges in the Sandbox.