Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. It's 100% free, no registration required.

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I noticed that my car's odometer was at 101101 when I got to work today. Which is a cool number because it's binary (and a palindrome, but that's not important). Now, I want to know when the next time I'll have a binary odometer reading. I can't read the odometer while I'm driving, because that would be dangerous, so it'll have to be binary either when I get to work or get home.

There's really bad traffic on the way to and from my office, so I have to take a different route each day.

For the purposes of this challenge, a day is a round trip and starts with my commute to work.

You'll need to take the initial reading of the odometer and a 10 element sequence representing the amount of miles each way. This sequence should be repeated until you get to a binary odometer reading. You should then output the number of days it takes until we get to a binary reading.

Both the milage for the route and the odometer reading will be positive integers. The count of days will either be x or x.5, so your output of the day count needs to support floating point for half days. If the day count is an integer, you don't need to output the .0. The odometer will always eventually reach a binary state.

Any form of input/output is acceptable and standard loopholes are disallowed.

Test cases:

101101, [27, 27, 27, 27, 27, 27, 27, 27, 27, 27] == 165.0
1, [13, 25, 3, 4, 10, 8, 92, 3, 3, 100] == 22.5
2, [2, 3, 1, 2, 7, 6, 10, 92, 3, 7] == 2.0
share|improve this question
    
Will a day result only ever be an integer or an integer plus a half? – FryAmTheEggman Feb 22 at 14:49
2  
@FryAmTheEggman Yes. Each step is half a day. – Morgan Thrapp Feb 22 at 14:49
5  
Where do you work/live that 3, 25 and 92 miles (km?) are regular acceptable commute distances? – kingofzeal Feb 22 at 21:27
1  
@kingofzeal A wormhole. – Morgan Thrapp Feb 22 at 21:30
1  
@TobySpeight It's a magical odometer with an infinite number of digits. – Morgan Thrapp Feb 23 at 15:39

12 Answers 12

up vote 3 down vote accepted

Jelly, 22 17 16 bytes

RịS+³DṀ=1
Ṡç1#SH

Try it online!

How it works

Ṡç1#SH     Main link. Left input: n (initial reading). Right input: A (distances)

Ṡ          Compute the sign of n. Since n is positive, this returns 1.
 ç         Apply the helper link to 1, 2, 3, ... until...
  1#         one match is found. Return the match in an array.
    S      Compute the sum of the array. This yields the match.
     H     Halve the result.


RịS+³DṀ=1  Helper link. Left argument: k (integer). Right argument: A (distances)

R          Range; yield [1, ..., k].
 ị         Retrieve the elements of A at those indices.
           Indexing in modular in Jelly.
  S        Compute the sum of the retrieved distances.
   +³      Add n (left input) to the sum.
     D     Convert the sum to base 10.
      Ṁ    Get the maximum digit.
       =1  Compare it with 1.
share|improve this answer

Javascript, 68 63 61 60 52 bytes

5 bytes off thanks @ETHproductions. 2 3 11!! bytes off thanks @NotthatCharles.

f=(i,a,m=0)=>/[^01]/.test(i+=a[m++%10])?f(i,a,m):m/2

Test here.

share|improve this answer
    
Darn, you beat me to it. – SuperJedi224 Feb 22 at 16:00
    
Would (i+=a[++m%10]) work? – ETHproductions Feb 22 at 16:54
    
@ETHproductions. Good one!! I forgot it will always be 10 – removed Feb 22 at 17:05
    
why not initialize r as 0.5? Or not initialize r or m whatsoever (they should default to null, ie., 0) – Not that Charles Feb 22 at 17:41
1  
You can also save a byte by making m=0 in the initializer and increment after modulo (m++%10)... at which point you can just drop r entirely. The whole method is then in the low 50s – Not that Charles Feb 22 at 18:22

MATL, 29 26 25 bytes

`tvyyYs+V50<!A~]xx1Mf1)2/

Input format is

[27; 27; 27; 27; 27; 27; 27; 27; 27; 27]
101101

EDIT (June 10, 2016): The following link replaces v by &v (26 bytes) to adapt to changes in the language

Try it online!

`              ]           % do---while loop. Exit loop when top of stack is falsy
 t                         % duplicate. Takes first input (array) first time
  v                        % concat vertically (doubles length of array)
   yy                      % copy top two. Takes second input (todasy's value) first time
     Ys                    % cumulative sum of (repeated) miles each way
       +                   % add to today's value
        V                  % convert each number to a string
         50<!A             % true for strings than only contain '01 ' (ASCII less than 50)
              ~            % negate. This is the loop condition
                xx         % delete stack contents
                  1M       % push again array that tells which strings only contain '01 '
                    f1)    % pick index of first true entry
                       2/  % divide by 2
share|improve this answer

Lua, 108 Bytes

First time using the repeat..until loop in a codegolf!

function f(o,t)i=0repeat i,o=i+1,(o+t[i%#t+1]).."."o=o:sub(1,o:find("%.")-1)until tonumber(o,2)print(i/2)end

Ungolfed

function f(o,t)               -- o can either be a number or a string, t is a table
                              -- call it like f(2,{27,14,5...})
  i=0                         -- initialise the travel count
  repeat                      -- proceed like a do..while in C
    i,o=i+1,(o+t[i%#t+1]).."."-- increment i, and add t[i] to the odometer
    o=o:sub(1,o:find("%.")-1) -- remove the decimal part of the odometer
  until tonumber(o,2)         -- tries to convert o from binary to decimal
                              -- return nil (and repeat the loop) if it can't
  print(i/2)                  -- print i/2 which is the number of days for i travels
end

After the first loop, o will have a decimal part because of tonumber, I had to remove it... And to add it for the first case, that's why I concatenate it with a ".".

share|improve this answer

Java, 112 miles bytes

float c(int r,int[]d){float y=0;for(int i=0;;i%=d.length){y+=.5;r+=d[i++];if((""+r).matches("[01]+"))return y;}}
share|improve this answer

05AB1E, 31 bytes

Code:

0IE\[²vs>sy+D§'aT«-""Qi\2/?}Ž}Ž

Somehow, the code doesn't stop running (and I can't figure out why). Apparently I forgot that there are three loops going on instead of 2. So it would still get into an infinite loop...

Try it online!

share|improve this answer

PowerShell, 84 73 67 59 57 bytes

param($a,$b)do{$a+=$b[$i++%10]}until(!+($a-replace1))$i/2

Takes input $a and $b, expecting $b to be an explicit array of mileages (e.g., .\binary-car.ps1 1 @(13,25,3,4,10,8,92,3,3,100)). We then enter a do/until loop. Each iteration, we increment $a with the mileage in $b at position $i++ % 10 so that we continually loop through the array. This will start at zero since for the first loop the $i is not initialized, and so evaluates to $null, which equates to 0 in this context, and it's only after that evaluation that the ++ occurs.

Then, the until statement checks if our number is only 0 and 1 by first -replaceing all 1 with nothing, casting that back as an integer with +, and then taking the Boolean-not with !. If it evaluates true, we'll finish the loop, output $i / 2, and terminate the program.

Explanation for the loop conditional -- In PowerShell, any non-zero integer is $true, and any non-empty string is also $true. For example, 231145 (an integer) will change to "2345" (a string) after the -replace, which will integer-cast as 2345 (an integer), the ! of which is $false. However, 101101 (an integer) will change to "00" (a string) which will cast as 0 (an integer), the ! of which is $true. If we didn't have the +, the "00" will ! to $false since it's a non-empty string.

Edit - Saved 11 bytes by swapping equality-on-length for strictly-zero
Edit 2 -- Saved another 6 bytes by realizing that $b.count will always be 10 ...
Edit 3 -- Saved another 8 bytes by using do/until instead of for
Edit 4 -- If the object being -replaced is an integer value, don't need quotes, saving another 2 bytes

share|improve this answer

Ruby, 58

Nothing special. Just a cycle...

->s,a,i=0{a.cycle{|e|i+=0.5;break i if/[2-9]/!~'%d'%s+=e}}
share|improve this answer
    
How do you run it? – bogl Feb 23 at 13:59
1  
@bogl It's a lambda - the easiest way is to append the params in square brackets. Or you can assign the lambda to a variable and, again, append params in square brackets. E.g., ->s,a,i=0{a.cycle{|e|i+=0.5;break i if/[2-9]/!~'%d'%s+=e}}[1, [13, 25, 3, 4, 10, 8, 92, 3, 3, 100]] or... f=->s,a,i=0{a.cycle{|e|i+=0.5;break i if/[2-9]/!~'%d'%s+=e}}; f[1, [13, 25, 3, 4, 10, 8, 92, 3, 3, 100]] – Not that Charles Feb 23 at 18:03

Mathematica, 92 bytes

(y=1;x=#+#2[[1]];While[!StringMatchQ[ToString@x,{"0","1"}..],x+=#2[[y++~Mod~10+1]]];N@y/2)&

Yep. Input is the odometer and a list of times. Output is the day count.

share|improve this answer

PHP, 102 98

function f($i,$s){while(1)foreach($s as$v){$d+=.5;$i+=$v;if(preg_match('/^[01]+$/',$i))return$d;}}

Ungolfed Version

function f($i,$s) {
    $d = 0;
    while(true) {
        foreach($s as $v) {
            $d += 0.5;
            $i+=$v;
            if(preg_match('/^[0|1]+$/', $i)) {
                return $d;
            }
        }
    }
}

PHP Notices can be removed of extra cost of 4 characters $d = 0; in golfed version.

Example

$i = 101101;
$s = [27, 27, 27, 27, 27, 27, 27, 27, 27, 27];
f($i,$s);
share|improve this answer
    
Removing the curly braces around the if, removing the 0 from 0.5, and removing the | between the 1 and 0 in your regex saves you 4 bytes. function f($i,$s){while(1)foreach($s as$v){$d+=.5;$i+=$v;if(preg_match('/^[01]+$/',$i))return$d;}} – Samsquanch Feb 23 at 14:37
    
@Samsquanch, good suggestion, brackets and 0 before .5 clearly I missed. Changed now. – kuldeep.kamboj Feb 24 at 4:47

Pyth, 36 32 30 bytes

Jvz.V0=J+J@QbI<ssM{`J2KbB;chK2

Try it here!

Explanation

Jvz.V0=J+J@QbI<ssM{`J2KbB;chK2  # Q = input sequence

Jvz                             # assign starting value to J
   .V0                          # Start an infinite loop iterating over b starting at 0
      =J                        # Set J to
        +J                      # the sum of J
          @Qb                   # and the value at Q[b % len(q)]
             I                  # if
              <      2          # lower than 2
                  {`J           # Remove duplicate digits from J 
               ssM              # Map the remaning digits back to integers and sum them
                      KbB       # if the above evals to true, save b to K and leave the loop
                         ;      # End loop body
                           hK   # Increment K because we missed one loop increment
                          c  2  # and divide it by 2 to get the days

share|improve this answer

C Sharp, 180.

Dear lord C# is long.

using System.Text.RegularExpressions;class a{double c(int a,int[]b){var d=0.5;a+=b[0];var i=1;while(!Regex.IsMatch(a.ToString(),"^[01]+$")){a+=b[i];i+=1;i=i%10;d+=0.5;}return d;}}
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.