23
\$\begingroup\$

Recently I had a Maths test and noticed that a certain number on the test matched an interesting pattern. The number (28384) matched a generic digit sequence that looks like this

(n)(x)(n+1)(x)(n+2)(x)(n+3) etc...

where n and x are single digit integers. The sequence can begin with either x or n and end with either x or n+y.

Your task is, given a multi digit positive integer, output a truthy or falsey value, depending on whether the input matches the pattern. The input will be between 4 and 18 digits long. You may take input as a string representation of the integer. The input will not begin with a 0 but can contain or end with 0s.

n+y will always be a single digit number (hence why the length limit is 18).

Test Cases

These should output a truthy value

182838485868788898
4344
85868
12223242526

And these should be falsey

12345
6724013635
36842478324836
1222232425
5859510511

As with all code golfs, shortest code wins! Good luck and may the odds, be ever in your favour!

\$\endgroup\$
  • \$\begingroup\$ Can we take input as a string? \$\endgroup\$ – Cows quack Jun 25 '17 at 10:59
  • \$\begingroup\$ @KritixiLithos "You may take input as a string representation of the integer." \$\endgroup\$ – Mr. Xcoder Jun 25 '17 at 10:59
  • \$\begingroup\$ Are both x and n non-zero for numbers that fit the rule? \$\endgroup\$ – Mr. Xcoder Jun 25 '17 at 11:20
  • \$\begingroup\$ @Mr.Xcoder the number cannot begin with a 0 but can contain or end with 0s \$\endgroup\$ – caird coinheringaahing Jun 25 '17 at 12:04

17 Answers 17

8
\$\begingroup\$

Python 2, 84 81 80 79 bytes

-1 byte thanks to ovs

lambda x:g(x,1)|g(x,0)
g=lambda x,a:len(set(x[a::2]))==(x[a<1::2]in"123456789")

Try it online!


Python 3, 82 79 78 77 bytes

lambda x:g(x,1)|g(x,0)
g=lambda x,a:len({*x[a::2]})==(x[a<1::2]in"123456789")

Try it online!

Slightly shorter in Python 3, but I didn't think it deserved its own answer.


Explanation

We set up a function g that takes string and an index (either 1 or 0). g then returns whether or not len(set(x[a::2])), that is the number of unique digits in every other position, is equal to (x[a==0::2]in"123456789"), whether or not the other digits are in ascending order. If the digits are in ascending order this returns whether or not they are all the same, if not it will ask if the set is empty, which it cannot be, thus always returning false.

\$\endgroup\$
  • \$\begingroup\$ As usual, I have been outgolfed >.< \$\endgroup\$ – Mr. Xcoder Jun 25 '17 at 11:41
  • \$\begingroup\$ x[a<1::2]in"123456789" can be "0"<x[a<1::2]<":" (comparing chars compares charcodes) \$\endgroup\$ – CalculatorFeline Jun 25 '17 at 17:24
  • \$\begingroup\$ @CalculatorFeline I do not think that is true. That just checks that the string begins with a number. \$\endgroup\$ – Sriotchilism O'Zaic Jun 25 '17 at 17:25
  • \$\begingroup\$ Oh right, however that works for single characters. \$\endgroup\$ – CalculatorFeline Jun 25 '17 at 17:45
  • \$\begingroup\$ But do you actually need a<1? Seems like that can be just a. \$\endgroup\$ – CalculatorFeline Jun 25 '17 at 17:47
4
\$\begingroup\$

Jelly, 13 11 bytes

Ds2ZI’M¦Ẏ¬Ạ

Try it online!

Explanation:

Ds2ZI’M¦Ẏ¬Ạ Accepts an integer
D           Get individual digits
  2         2
 s          Split into chunks of specific length
   Z        Zip
    I       Take deltas
     ’      Decrement
      M     Take maximal indices
       ¦    Apply at specific indices
        Ẏ   Reduce dimensionality
         ¬  Vectorized NOT
          Ạ Check if all are truthy
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 15 bytes

TG9LNýN.øŒ})˜Iå

Try it online!

Explanation

TG9LNýN.øŒ})˜Iå
TG        }     # For 1 to 9...
  9L             # Push [1 .. 9]
    Ný           # Join with current value 
      N.ø        # surround with current value
         Π      # Push substrings
           )    # Wrap stack to array
            ˜   # Deep flatten the array
             I  # Push input
              å # Is the input in the array?
                # Implicit print

It should work (test cases did) but if you find any flaws please let me know.

14 Bytes if no output counts as falsy:

TG9LNýN.øŒIåi1
\$\endgroup\$
2
\$\begingroup\$

D, 117 bytes

int f(string n){int o=n[0]!=n[2],x=n[o];foreach(i,c;n){if(i%2!=o&&i>1&&c!=n[i-2]+1||i%2==o&&c!=x)return 0;}return 1;}

Definitely suboptimal, but it works fine

Try It Online!

\$\endgroup\$
2
\$\begingroup\$

Haskell, 108 113 97 95 bytes

d(x:_:r)=x:d r
d r=r
c(x:n:r)=and$all(==x)(d r):zipWith(==)(d$n:r)[n..]
f s@(_:n:_)=c s||c(n:s)

Sample call: f "182838485868788898" yields True

Ungolfed version with explanations:

-- Take every other element from the string, starting with the first
d (x:_:r) = x : d r
d r       = r
c (x:n:r) = and $ all (== x) (d r)              -- Every other char is equal to the first
                : zipWith (==) (d $ n:r) [n..]  -- The remaining chars are a prefix of n(n+1)(n+2)...
f s@(_:n:_) = c s      -- The case where s already starts with x
           || c (n:s)  -- If not, prepend a dummy x and try again
\$\endgroup\$
  • 2
    \$\begingroup\$ Welcome to PPCG and Haskell golfing in particular! isPrefixOf is not in Prelude, so you have to include import Data.List in your code or use an alternative, e.g. and(zipWith(==)(n:r)[n..]). \$\endgroup\$ – Laikoni Jun 25 '17 at 13:11
  • \$\begingroup\$ @Laikoni: Thanks for the hint! I replaced the function accordingly. \$\endgroup\$ – siracusa Jun 25 '17 at 13:18
  • 1
    \$\begingroup\$ I think x/=y can just be 1>0 because if not x/=y then x==y and the first case catches it. \$\endgroup\$ – CalculatorFeline Jun 25 '17 at 17:21
  • \$\begingroup\$ You also don't need the where, defining c and d as auxiliary functions outside of f is fine. f can then be shortened to f s@(_:n:_)=c s||c(n:s). \$\endgroup\$ – Laikoni Jun 25 '17 at 18:13
  • 1
    \$\begingroup\$ Then you might be interested in the guide to golfing rules in Haskell. Even though it's not a rule, you could use newlines instead of ;. It's the same byte count but improves the readability of the code. \$\endgroup\$ – Laikoni Jun 25 '17 at 21:26
1
\$\begingroup\$

JavaScript (ES6), 66 63 60 bytes

Takes input as a string.

s=>[...s].every((d,i)=>d-s[j^(k=i+j&1)]==k*i>>1,j=s[2]-s[0])

Test cases

let f =

s=>[...s].every((d,i)=>d-s[j^(k=i+j&1)]==k*i>>1,j=s[2]-s[0])

console.log('[Truthy]');
console.log(f("182838485868788898"))
console.log(f("4344"))
console.log(f("85868"))
console.log(f("12223242526"))

console.log('[Falsy]');
console.log(f("12345"))
console.log(f("6724013635"))
console.log(f("36842478324836"))
console.log(f("1222232425"))

\$\endgroup\$
1
\$\begingroup\$

C (gcc), 123 bytes

#define X*s&&*s++-++n&&(r=0)
t,n,x,r;f(char*s){t=*s==s[2];for(r=1,n=s[t],x=s[!t],s+=2;*s;)t||X,*s&&*s++-x&&(r=0),t&&X;n=r;}

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Python 3, 99 96 89 bytes

  • Saved 3 bytes: use of all() function
  • @WheatWizard saved 7 bytes:shorthanding & | and replace extra variable by k<1
lambda x,g=lambda x,k:(x[k<1::2]in'123456789')&all(j==x[k]for j in x[k::2]):g(x,0)|g(x,1)

Try it online!

Explanation:

First split the string into two lists: one with odd-indexed and other with even-indexed elements. The two lists A and B are supposed be such that either:

  1. A contains same number and B contains consecutive numbers in ascending order.

OR just the opposite

  1. B contains same number and A contains consecutive numbers in ascending order.

The consecutive condition is checked by: a in '123456789'

The same-number condition is checked by: all(i=a[x] for i in a)

\$\endgroup\$
  • 1
    \$\begingroup\$ you can replace instances of i with k<1 and drop the i argument all together. \$\endgroup\$ – Sriotchilism O'Zaic Jun 25 '17 at 13:00
  • 1
    \$\begingroup\$ You can also surround the first predicate in parens and use & instead of and. Your or can be replaced with | as well. \$\endgroup\$ – Sriotchilism O'Zaic Jun 25 '17 at 13:01
  • 1
    \$\begingroup\$ I see this eventually converging towards your answer.. :D \$\endgroup\$ – officialaimm Jun 25 '17 at 13:05
1
\$\begingroup\$

PHP, 68 bytes

for(;$v<10;)$s.=strstr(+$v.join(+$v,range(1,9)).+$v++,$argn);echo$s;

Try it online!

Output part of search string starting from and including the first occurrence of input to the end of search string as truthy value and nothing for falsy

for 2 Bytes more you can replace echo$s; with !!echo$s; to get 1 as truthy value

Find the occurrence of the input in one of the following strings in the array

Array
(
    [0] => 0102030405060708090
    [1] => 1112131415161718191
    [2] => 2122232425262728292
    [3] => 3132333435363738393
    [4] => 4142434445464748494
    [5] => 5152535455565758595
    [6] => 6162636465666768696
    [7] => 7172737475767778797
    [8] => 8182838485868788898
    [9] => 9192939495969798999
)
\$\endgroup\$
1
\$\begingroup\$

JavaScript (ES6), 54 bytes

f=
s=>[...s].every((e,i)=>i<2|e-s[i-2]==(s[2]!=s[0])^i%2)
<input oninput=o.textContent=this.value[3]?f(this.value):``><pre id=o>

Takes input as a string.

\$\endgroup\$
1
\$\begingroup\$

MATL, 15 bytes

2L&),duw]hSFTX=

Try it online!

With some help of @LuisMendo in chat. Note that, if empty output + error is also considered 'falsy', the X can be left out, bringing the score to 14 bytes.

2L&)     % Split the input into odd and even-indexed elements
    ,   ] % Do twice (new feature since MATL v20.0), i.e., on both halves of the input
     d     % Pairwise differences of the array. Results in [0,0,...] for the 'constant' part,
            %  and [1,1,...] for the 'increasing' part.
      u      % Get unique elements. Results in [0] for the constant part, [1] for the increasing part.
       w      % Swap the stack to do the same for the other half of the input.
         hS    % Horizontal concatenation followed by sort. Results in [0,1] for the desired string.
           FTX= % Check if the result is indeed [0,1]. Implicit display.
\$\endgroup\$
0
\$\begingroup\$

Mathematica, 121 bytes

(m[x_]:=Take[s=IntegerDigits@#,{x,Length@s,2}];w[b_,n_]:=Union@Differences@m@b=={1}&&Length@Union@m@n==1;w[1,2]||w[2,1])&
\$\endgroup\$
0
\$\begingroup\$

Pyth, 20 bytes

ASm.+sMd.Tcz2&-GZ-H1

Output [] when the number matches the digit pattern, anything else otherwise.

Try it online!

Explanations (example with input 85868)

ASm.+sMd.Tcz2&-GZ-H1

          cz2           # Chop the input in pairs: ['85', '86', '8']
        .T              # Transpose, ignore absences: ['888', '56']
     sM                 # Convert to integers: [[8, 8, 8], [5, 6]]
  m.+  d                # Compute deltas: [[0, 0], [1]]
 S                      # Sort: [[0, 0], [1]]
A                       # Assign first list to G and second list to H
              -GZ       # Filter 0 on G (on absence): [0, 0] -> []
                 -H1    # Filter 1 on H (on absence): [1] -> []
             &          # Check both lists are empty (logical and): [] & [] -> []
\$\endgroup\$
0
\$\begingroup\$

Pyth, 17 bytes

qU2Ssm{.+d.TcjQT2

Try it here

Same algorithm as my Jelly answer.

Explanation:

qU2Ssm{.+d.TcjQT2 Accepts an integer
             jQT  Take digits of input
            c   2 Split in pairs
          .T      Transpose
     m            Map the following on each of the two resulting lists:
       .+d          Take deltas
      {             Deduplicate
    s             The list is now in [[a, b, ...], [A, B, ...]] format, convert it to [a, b, ..., A, B, ...]
   S              Sort
qU2               Check if equal to [0, 1]
\$\endgroup\$
0
\$\begingroup\$

Python 3, 167 161 157 131 106 bytes

-55 bytes thanks to @WheatWizard's suggestions

def g(t):k,c,f,j=t[::2],t[1::2],'123456789',''.join;return(len({*k})and j(c)in f)or(len({*c})and j(k)in f)

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Can be golfed further. I already edit. \$\endgroup\$ – Mr. Xcoder Jun 25 '17 at 11:29
  • \$\begingroup\$ You might have seen this trick in my answer but set(c) is the same as {*c}. (at least in python 3) \$\endgroup\$ – Sriotchilism O'Zaic Jun 25 '17 at 11:42
  • \$\begingroup\$ @WheatWizard thanks. Editing \$\endgroup\$ – Mr. Xcoder Jun 25 '17 at 12:02
  • 3
    \$\begingroup\$ [t[z]for z in range(0,len(t),2)] is also just a list splice. You can do this simply with t[::2]. If you are not familiar with this syntax, I suggest giving a look over the docs, because it is pretty useful. \$\endgroup\$ – Sriotchilism O'Zaic Jun 25 '17 at 12:52
  • \$\begingroup\$ @WheatWizard Wow, that is really useful. Sadly, I cannot edit the answer right now. I will do so as soon as I can. Thaks a lot for the advice... \$\endgroup\$ – Mr. Xcoder Jun 25 '17 at 13:01
0
\$\begingroup\$

Java (OpenJDK 8), 128 119 118 108 107 104 bytes

s->{int i=3,a=s[2]-s[0],b=s[3]-s[1];for(;++i<s.length;)a+=b-(b=s[i]-s[i-2]==a?a:2);return(a|b)==1&a!=b;}

Try it online!

Explanation:

s->{                             // lambda
  int i=3,                       //  iterating index
      a=s[2]-s[0],               //  diff of even-indexed characters
      b=s[3]-s[1];               //  diff of odd-indexed characters
  for(;++i<s.length;)            //  iterate
    a+=b-(b=                     //   swap a and b
        s[i]-s[i-2]==a?a:2       //    or set b to 2 if the diffs don't match
      ));                        //
  return (a|b)==1                //  return true if both a and b are in (0,1)
        &a!=b;                   //         but different
}
\$\endgroup\$
0
\$\begingroup\$

Retina, 47 bytes

.
$*11;
(1+)(?<=\1;1+;\1)

^1+;1+

^;?(;1;)+;?$

Try it online!

Outputs 1 if it matches the pattern, 0 if it does not

Explanation

.
$*11;

Convert each digit n to n+1 in unary, separated by semicolons

(1+)(?<=\1;1+;\1)

(Trailing newline) converts each digit to the difference between itself and the one 2 spots before it

^1+;1+

(Trailing newline) removes the first 2 digits

^;?(;1;)+;?$

Counts the number of matches of this pattern, which checks for alternating 0s and 1s

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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