29
\$\begingroup\$

A staircase number is a positive integer x such that its nth digit (one indexed starting with the least significant digit) is equal to x % (n + 1). Thats a bit of a mouthful so lets look at an example. Take 7211311, if we take the modular residues of 7211311 on the range 2-8 we get the following:

7211311 % 2 = 1
7211311 % 3 = 1
7211311 % 4 = 3
7211311 % 5 = 1
7211311 % 6 = 1
7211311 % 7 = 2
7211311 % 8 = 7

These are the digits of 7211311! Thus 7211311 is a staircase number.

Task

Write code that takes when given a positive number as input, will output two distinct values one if the number is a staircase number and the other if it is not.

This is a competition so your aim should be to minimize the number of bytes in your source code.

Test Cases

Here are the first 13 staircase numbers:

1, 10, 20, 1101, 1121, 11311, 31101, 40210, 340210, 4620020, 5431101, 7211311, 12040210
\$\endgroup\$
  • \$\begingroup\$ Isn't 0 a staircase numbers? A lot of answers think so. \$\endgroup\$ – Okx Jul 2 '17 at 10:40
  • 3
    \$\begingroup\$ @Okx the task is just to distinguish positive staircase numbers from positive non-staircase numbers, so the behavior is undefined for 0 and negative numbers. \$\endgroup\$ – Paŭlo Ebermann Jul 2 '17 at 12:40

26 Answers 26

10
\$\begingroup\$

Haskell, 55 57 bytes

f m|let n#x=n==0||n`mod`10==m`mod`x&&div n 10#(x+1)=m#2

A different approach than the other Haskell solution.

Thanks xnor for saving 2 bytes.

\$\endgroup\$
  • 4
    \$\begingroup\$ You can use this tip to shorten the let expression. \$\endgroup\$ – xnor Jul 1 '17 at 20:23
  • \$\begingroup\$ A different, shorter approach. Well done! +1 \$\endgroup\$ – qfwfq Jul 2 '17 at 3:47
9
\$\begingroup\$

Brachylog, 25 21 16 14 bytes

{it+₂;?↔%}ᶠ↔c?

Try it online!

First Brachylog submission :D probably very ungolfed...many thanks to Leaky Nun and Fatalize for encouragement and help to golf this from 25 all the way down to just 14. :) :)

\$\endgroup\$
7
\$\begingroup\$

Javascript, 42 41 39 38 bytes

-4 bytes thanks to @Shaggy and @ETHProductions

s=>[...s].some(d=>s%i++^d,i=~s.length)

This takes the number as a string and returns false if the number is a staircase number and true otherwise.

Example code snippet:

f=
s=>[...s].some(d=>s%i++^d,i=~s.length)

function update() {
  o.innerText = f(document.getElementById("i").value)
}
<input id="i" type="number">
<button onclick="update()">Test</button>
<p id="o">

\$\endgroup\$
  • 2
    \$\begingroup\$ You should be able to drop the ! as the challenge doesn't explicitly specify that you must return true for true and false for false, simply that you must return 2 distinct values. \$\endgroup\$ – Shaggy Jul 1 '17 at 16:01
  • 2
    \$\begingroup\$ This is very well golfed, well done. I think you should be able to squeeze out two more bytes if you calculate i yourself: s=>[...s].some(d=>s%i--^d,i=s.length+1) \$\endgroup\$ – ETHproductions Jul 1 '17 at 16:05
  • 2
    \$\begingroup\$ Actually, by exploiting the fact that ~x == -(x+1) on integers and x%-y == x%y, I think you can get one more: s=>[...s].some(d=>s%i++^d,i=~s.length) \$\endgroup\$ – ETHproductions Jul 1 '17 at 16:10
6
\$\begingroup\$

05AB1E, 6 bytes

Code:

ā>%JRQ

Uses the 05AB1E encoding. Try it online!

Explanation:

ā        # Get the range [1 .. len(input)]
 >       # Increment by 1
  %      # Vectorized modulo
   J     # Join the array into a single number
    RQ   # Reverse that number and check if it's equal to the original input
\$\endgroup\$
6
\$\begingroup\$

Haskell, 60 bytes

Takes the number as an int

x n|s<-show n=reverse s==(rem n.(+1)<$>[1..length s]>>=show)
\$\endgroup\$
5
\$\begingroup\$

Mathematica, 60 bytes

FromDigits@Reverse@Mod[#,Range@Length@IntegerDigits@#+1]==#&

Try it online!

@alephalpha golfed it to 48

Mathematica, 48 bytes

FromDigits@Reverse@Mod[#,Range[2,Log10@#+2]]==#&

next one is 24120020

\$\endgroup\$
5
\$\begingroup\$

Python 2, 54 bytes

f=lambda n,x=0:10**x>n or(`n%(x+2)`==`n`[~x])*f(n,x+1)

Try it online!

\$\endgroup\$
5
\$\begingroup\$

Japt, 9 7 bytes

Takes input as a string.

¥£%´JÃw

Test it

  • 2 bytes saved with help from ETHproductions.

Explanation

We implicitly take the string as input.

£   Ã

Map over each character in the string.

´J

J is the Japt constant for -1, and ´ decrements it by 1 on each pass (-- in JavaScript). So, on the first pass, this gives us -2.

%

We use that value to perform a modulo operation on the input string which is automatically cast to an integer in the process. In JavaScript x%-y gives the same result as x%y.

w

Reverse the resulting string.

¥

Check if the new string is equal to the original input and implicily output the result as a boolean.

\$\endgroup\$
  • \$\begingroup\$ Gosh darn (Y+2, I feel like that could be at least 1 byte shorter... \$\endgroup\$ – ETHproductions Jul 1 '17 at 15:29
  • 1
    \$\begingroup\$ ...and it can: ¥£%´JÃw :-) (works because x%y == x%-y in JS) \$\endgroup\$ – ETHproductions Jul 1 '17 at 15:31
  • \$\begingroup\$ Aha, yes, was trying a few different things to get that calculation down to 2 bytes. \$\endgroup\$ – Shaggy Jul 1 '17 at 15:47
4
\$\begingroup\$

Neim, 6 bytes

𝐧ᛖ𝕄𝐫𝐣𝔼

Explanation:

𝐧         Get the length of the input, then create an exclusive range
 ᛖ        Add 2 to each element
  𝕄       Modulus
    𝐫      Reverse
     𝐣     Join
      𝔼   Check for equality

Try it online!

\$\endgroup\$
  • \$\begingroup\$ @Thehx Regarding your edit, Neim uses a custom encoding: this one \$\endgroup\$ – Okx Jul 5 '17 at 15:24
2
\$\begingroup\$

Jelly, 7 bytes

DJ‘⁸%⁼Ṛ

Try it online!

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

Python 2, 56 bytes

lambda x:all(`x%(i+2)`==`x`[~i]for i in range(len(`x`)))

Try it online!

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

Perl 6, 32 bytes

{$_ eq[~] $_ «%«(1+.comb...2)}

Try it online!

  • .comb is the number of characters in the string representation of the input argument $_ (that is, the number of digits).
  • 1 + .comb ... 2 is the sequence of numbers from one greater than the number of digits down to 2.
  • «%« is the modulus hyperoperator that gives the remainder when $_, the input argument on its left, is divided by each of the elements of the sequence on its right: $_ % 2, $_ % 3, ....
  • [~] concatenates those digits into a new number, which is compared with the input argument using the string equality operator eq.
\$\endgroup\$
2
\$\begingroup\$

PHP, 43 bytes

for(;$r<$a=$argn;)$r=$a%~++$i.$r;echo$r>$a;

Try it online!

PHP, 44 bytes

prints 1 for true and nothing for false

for(;$r<$a=$argn;)$r=$a%~++$i.$r;echo$r==$a;

Try it online!

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

Pyth, 13 bytes

-1 bytes thanks to Okx.

qsjk_m%QhdSl`

Try it online!

Explanation

             QQ    # Implicit input
          Sl`Q     # Generate [1, len(str(Q))]
     m%Qhd         # For digit d in above range, perform Q % (d + 1)
 sjk_              # Reverse, then convert to number
q             Q    # Test equality with input

Alternate solution, still 13 bytes (thanks to karlkastor)

qi_.e%Q+2k`QT

Try it online! That's essentially the same as the first solution, excepted that it uses i to convert from array of numbers to a number, and that the range is generated differently.

\$\endgroup\$
  • 1
    \$\begingroup\$ You can replace ss`M_ with jk_ to save 2 bytes. \$\endgroup\$ – Okx Jul 1 '17 at 17:13
  • \$\begingroup\$ @Okx I need it because j outputs a string whereas I need a number to compare with the input (which is a number). \$\endgroup\$ – Jim Jul 1 '17 at 17:59
  • 1
    \$\begingroup\$ Another 13 byte solution would be: qi_.e%Q+2k`QT using enumerated map (.e) instead of map. And converting the remainders to a base 10 int from the list instead of using join. \$\endgroup\$ – KarlKastor Jul 1 '17 at 18:13
2
\$\begingroup\$

C++,104 bytes

1) original version:

int main(){int N,T,R=1;cin>>N;T=N;for(int i=1;i<=log10(N)+1;i++){if(N%(i+1)!=T%10){R=0;}T/=10;}cout<<R;}

2) in a readable form:

int main()
{
    int N, T, R = 1;

    cin >> N;
    T = N;

    for (int i = 1; i <= log10(N) + 1; i++)
    {
        if (N % (i + 1) != T % 10)
        {
            R = 0;
        }

        T /= 10;
    }

    cout << R;
}

Try it Online!

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

Pari/GP, 42 bytes

n->Vecrev(s=digits(n))==[n%d|d<-[2..#s+1]]

Try it online!

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

Python 2, 66 60 58 57 bytes

  • Thanks to @Leaky nun for 6 bytes: remove unneeded x and (shouldnot check for 0)
  • Thanks to @Einkorn Enchanter for 1 byte: use of enumerate
lambda x:all(a==`x%(i+2)`for i,a in enumerate(`x`[::-1]))

Try it online!

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

Python 3: 63 Bytes

lambda m:all(int(x)==m%(n+2)for n,x in enumerate(str(m)[::-1]))

If I could count the number of times I wished 'enumerate' were shorter...

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Yep, and I just realized its exactly the same as the answer @officialaimm gave... Should I remove? \$\endgroup\$ – bendl Jul 5 '17 at 14:41
  • \$\begingroup\$ Theirs is in python 2 and you came up with it independently so I would leave it. \$\endgroup\$ – Sriotchilism O'Zaic Jul 5 '17 at 14:44
  • \$\begingroup\$ Can save two bytes by starting your enumeration at 2 and rearranging the logical: lambda m:all(m%n==int(x)for n,x in enumerate(str(m)[::-1],2)) \$\endgroup\$ – nocturama Jul 5 '17 at 15:48
1
\$\begingroup\$

Java (OpenJDK 8), 60 bytes

n->{int m=2,r=0,t=1;for(;n>=t;t*=10)r+=n%m++*t;return r==n;}

Try it online!

A non-string version.

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

Java 8, 156 149 bytes

interface B{static void main(String[]s){String f="";for(int i=1;i<=s[0].length();)f=new Long(s[0])%++i+f;System.out.print(f.equals(s[0]));}}

Ungolfed :

interface B {
    static void main(String[] s) {
        String f = "";
        for (int i = 1; i <= s[0].length();)
            f = new Long(s[0]) % ++i + f;
        System.out.print(f.equals(s[0]));
    }
}

Try it Online !

UPDATE :
-7 bytes : removed useless {} and replaced Integer.parseInt(...) by new Integer(...)
-9 bytes : thanks to Kevin Cruijssen, removed a bunch of useless (), used Long instead of Integer and print instead of println. Thanks Kévin !

\$\endgroup\$
  • 1
    \$\begingroup\$ Nice answer, +1 from me. Btw, some small things to golf: new Integer can be new Long (-3 bytes); println can be print (-2 bytes); and you can remove the parenthesis surrounding new Long(s[0])%i+f; (-4 bytes). \$\endgroup\$ – Kevin Cruijssen Jul 5 '17 at 12:29
  • \$\begingroup\$ Really nice ! Thanks, i'll update this ! \$\endgroup\$ – Alex Ferretti Jul 6 '17 at 12:45
1
\$\begingroup\$

Charcoal, 20 15 bytes

⌊Eθ⁼ιI﹪Iθ⁻⁺¹Lθκ

Try it online! Outputs - for a staircase number, nothing otherwise. Link is to verbose version of code.

\$\endgroup\$
0
\$\begingroup\$

Python 2, 61 bytes

lambda x:[`x%(n+2)`for n in range(len(`x`))][::-1]==list(`x`)
\$\endgroup\$
  • \$\begingroup\$ Nope, your new golf is a byte shorter. :) \$\endgroup\$ – Sriotchilism O'Zaic Jul 1 '17 at 15:15
0
\$\begingroup\$

q/kdb+, 34 bytes

Solution:

{s~raze($)x mod'2+(|)(!)(#)s:($)x}

Example:

q){s~raze($)x mod'2+(|)(!)(#)s:($)x}7211311 / this is a staircase number (true)
1b
q){s~raze($)x mod'2+(|)(!)(#)s:($)x}7211312 / this is not (false)
0b
q)t(&){s~raze($)x mod'2+(|)(!)(#)s:($)x}each t:1 + til 1000000 / up to a million
1 10 20 1101 1121 11311 31101 40210 340210

Explanation:

Cast the input number to a string, count from 0..length of string, add 2 to all, reverse it and feed each number into mod along with the original input. Cast the result of the mod to a string and reduce the list, check if it is equal to the string of the input number:

{s~raze string x mod'2 + reverse til count s:string x} / ungolfed solution
{                                                    } / lambda function
                                           s:string x  / convert input to string, save as s
                                     count             / return length of this string
                                 til                   / like python's range() function
                         reverse                       / reverses the list
                     2 +                               / adds two to each element in the list
               x mod'                                  / ' is each both, so feeds x, and each element of the list to modulo function
        string                                         / converts output list to string list ("7";"2";"1"..etc)
   raze                                                / reduce list ("721...")
 s~                                                    / is s equal to this reduced list, returns boolean

Notes:

Most of the solution is for generating the 2,3,4.. list, I have another solution that does less stuff, but winds up being 37 bytes after golfing:

{s~x mod'reverse 2 + til count s:("J"$) each string x} / ungolfed
{s~x mod'(|)2+til(#)s:("J"$)each($)x}                  / golfed
\$\endgroup\$
0
\$\begingroup\$

Clojure, 75 bytes

#(=(sort %)(sort(map(fn[i c](char(+(mod(Integer. %)(+ i 2))48)))(range)%)))

Input is a string, using map and the trailing % ended up being shorter than for[i(range(count %))] approach.

\$\endgroup\$
0
\$\begingroup\$

Haskell, 62 bytes

f x=and$zipWith(==)(reverse$show x)$map(head.show.mod x)[2..]

Instead of reversing the (infinite) list of moduli, it truncates the list by zipping it with the reversed string-respresentation of the integral x, which it then ensures is equal element-wise.

\$\endgroup\$
0
\$\begingroup\$

Perl 5, 41 bytes

39 bytes of code + 2 flags -pa

map{$\||=$_!=$F[0]%++$n}0,reverse/./g}{

Try it online!

Outputs nothing (undef) for staircase numbers, 1 for anything else

\$\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.