24
\$\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\$
4
  • \$\begingroup\$ Can we take input as a string? \$\endgroup\$
    – user41805
    Jun 25, 2017 at 10:59
  • \$\begingroup\$ @KritixiLithos "You may take input as a string representation of the integer." \$\endgroup\$
    – Mr. Xcoder
    Jun 25, 2017 at 10:59
  • \$\begingroup\$ Are both x and n non-zero for numbers that fit the rule? \$\endgroup\$
    – Mr. Xcoder
    Jun 25, 2017 at 11:20
  • \$\begingroup\$ @Mr.Xcoder the number cannot begin with a 0 but can contain or end with 0s \$\endgroup\$ Jun 25, 2017 at 12:04

20 Answers 20

9
\$\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\$
7
  • \$\begingroup\$ As usual, I have been outgolfed >.< \$\endgroup\$
    – Mr. Xcoder
    Jun 25, 2017 at 11:41
  • \$\begingroup\$ x[a<1::2]in"123456789" can be "0"<x[a<1::2]<":" (comparing chars compares charcodes) \$\endgroup\$ Jun 25, 2017 at 17:24
  • \$\begingroup\$ @CalculatorFeline I do not think that is true. That just checks that the string begins with a number. \$\endgroup\$
    – Wheat Wizard
    Jun 25, 2017 at 17:25
  • \$\begingroup\$ Oh right, however that works for single characters. \$\endgroup\$ Jun 25, 2017 at 17:45
  • \$\begingroup\$ But do you actually need a<1? Seems like that can be just a. \$\endgroup\$ Jun 25, 2017 at 17:47
5
\$\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\$
3
\$\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\$
3
\$\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\$
3
\$\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\$
7
  • 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, 2017 at 13:11
  • \$\begingroup\$ @Laikoni: Thanks for the hint! I replaced the function accordingly. \$\endgroup\$
    – siracusa
    Jun 25, 2017 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\$ Jun 25, 2017 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, 2017 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, 2017 at 21:26
2
\$\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\$
2
\$\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\$
2
\$\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\$
3
  • 1
    \$\begingroup\$ you can replace instances of i with k<1 and drop the i argument all together. \$\endgroup\$
    – Wheat Wizard
    Jun 25, 2017 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\$
    – Wheat Wizard
    Jun 25, 2017 at 13:01
  • 1
    \$\begingroup\$ I see this eventually converging towards your answer.. :D \$\endgroup\$ Jun 25, 2017 at 13:05
2
\$\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\$
2
\$\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\$
2
\$\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\$ @CzylabsonAsa Thanks for pointing it out, it seems as if a ) got put in the wrong place for some reason. \$\endgroup\$
    – Neil
    Jul 5, 2022 at 20:26
2
\$\begingroup\$

Julia, 57 56 bytes

~s=(!x=occursin(s,join(x*k for k='0':'9')x);!s[1]|!s[2])
  • replace || by | by @MarcMush

Attempt This Online!

  • input: the number as decimal string
\$\endgroup\$
1
  • \$\begingroup\$ you can use | instead of || \$\endgroup\$
    – MarcMush
    Jul 5, 2022 at 21:18
1
\$\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\$
1
\$\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\$
1
\$\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\$
1
\$\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\$
5
  • \$\begingroup\$ Can be golfed further. I already edit. \$\endgroup\$
    – Mr. Xcoder
    Jun 25, 2017 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\$
    – Wheat Wizard
    Jun 25, 2017 at 11:42
  • \$\begingroup\$ @WheatWizard thanks. Editing \$\endgroup\$
    – Mr. Xcoder
    Jun 25, 2017 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\$
    – Wheat Wizard
    Jun 25, 2017 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, 2017 at 13:01
1
\$\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\$
1
\$\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\$
1
\$\begingroup\$

Husk, 19 bytes

S¤|o←Ẋ~&Λȯ¬→-E↔TC2d

Try it online!

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

Vyxal, 11 bytes

y"v¯vUfsk≈⁼

Try it Online!

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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