Superstitious hotel elevator

54

8

Description

Here's a very superstitious hotel elevator in Shanghai:

               enter image description here

It avoids the number 13, because thirteen is unlucky in the Western world, and it avoids the digit 4, because four is unlucky in parts of Asia. What if this hotel was taller?

Read a positive even integer n from STDIN, representing the number of floors, and print what the button layout would look like to STDOUT: -1, followed by the next n-1 positive integers that aren't equal to 13 and don't contain digit 4. Arrange these numbers in two columns such as in the above image: print two floor numbers per line, separated by a horizontal tab, so that reading the lines in reverse order from left-to-right yields the sequence in ascending order. (You may optionally print a trailing newline character, too.)

Test cases

For the input 14, output should be as in the above image:

15  16
11  12
9   10
7   8
5   6
2   3
-1  1

where the whitespace in each line is a single horizontal tab character.

For the input 2, you should print -1 1.

For the input 100, you should print:

120 121
118 119
116 117
113 115
111 112
109 110
107 108
105 106
102 103
100 101
98  99
96  97
93  95
91  92
89  90
87  88
85  86
82  83
80  81
78  79
76  77
73  75
71  72
69  70
67  68
65  66
62  63
60  61
58  59
56  57
53  55
51  52
39  50
37  38
35  36
32  33
30  31
28  29
26  27
23  25
21  22
19  20
17  18
15  16
11  12
9   10
7   8
5   6
2   3
-1  1

Goal

This is . Shortest answer in bytes wins.

Lynn

Posted 2016-01-08T03:06:27.220

Reputation: 55 648

Wouldn't they also avoid n13? – Conor O'Brien – 2016-01-08T03:12:58.593

1I don't think anyone considers e.g. 6138 an unlucky number over here. Either way, you should print integers that contain 13 but aren't equal to it. – Lynn – 2016-01-08T03:25:01.710

Okay, cool! (filler) – Conor O'Brien – 2016-01-08T03:25:31.280

2@Mauris 6138, maybe not, but 113? I think the key would be whether you say "thirteen" when you read the number out loud. – Random832 – 2016-01-08T05:41:17.983

Also, how tall can the hotel get? What about floor 666 (which occurs at 456 floors in the "standard" version, and 449 in the more aggressively 13-avoiding version) – Random832 – 2016-01-08T05:46:32.897

12@Random832 What you suggest are effectively arbitrary changes to the spec. The PPCG etiquette discourages such changes after answers have been given, especially if existing answers are effectively invalidated, which they would be in this case – Digital Trauma – 2016-01-08T06:08:30.307

8FWIW, 4 isn't unlucky. 4 just sounds very similar to "die" or "death" in the various chinese dialects/languages. – slebetman – 2016-01-08T07:44:23.660

Is it acceptable if the numbers within each column are right-aligned? I guess yes, because the challenge doesn't say anything about it, but just to double check. Also, will the inohut number always be even? What if it's odd? – Luis Mendo – 2016-01-08T09:39:22.157

@Mauris is there a limit of the number of floors we have to be able to process? Are the chinese going to build a space elevator? – x13 – 2016-01-08T12:10:34.567

@Random832, I'm not changing the spec. Only avoid 13 or numbers containing 4. – Lynn – 2016-01-08T15:04:50.893

2@ThisNameBetterBeAvailable: If your program is limited by something like integer overflow, that's fine, but if your language of choice handles arbitrary-precision integer arithmetic, your code should theoretically work for any input size. – Lynn – 2016-01-08T15:07:10.467

@LuisMendo I'm not sure what you mean: I assume you are working in some programming language that can format the output for you and print a nice two-column table. In the interest of fairness, I would like everyone's output to be exactly of the form 15\t16\n12\t11\n..., so what you write would not be allowed. – Lynn – 2016-01-08T15:08:51.743

10@slebetman: Well, yes, that's why 4 is unlucky. It's still superstition, whatever the origin is! But that's getting a bit off-topic. – Lynn – 2016-01-08T15:12:15.800

1@Mauris my submission can calculate just enough floors to get around the earth, but it can't reach the moon... yet. Time to bring out the ULL's – x13 – 2016-01-08T15:22:31.683

13Wait! Counting the buttons I see that hotel has exactly 13 floors (excluding the basement.) There's no way I'm staying there! – Level River St – 2016-01-08T18:42:10.647

And apparently, zero is unlucky somewhere as well. USA, I think. – orion – 2016-01-11T10:20:59.127

1How should odd inputs be treated? – Black Owl Kai – 2019-01-19T20:55:54.353

@BlackOwlKai The problem says, “Read a positive even integer n from STDIN”… Here on PPCG, that means you can assume the output is indeed a positive even integer. Your solution may handle invalid inputs (odd, negative, zero…) in whatever way it likes. – Lynn – 2019-01-21T16:30:47.547

Answers

8

Pyth, 27 bytes

jjLC9_c+_1.f&!@\4`ZnZ13tQ)2

Try it online here.

Gets .first Q-1 numbers that match the filter !=13 and 4 isn't in the string representation of the number. Then it prepends -1 , chops in half, joins each by tabs(C9) and joins by newlines.

Maltysen

Posted 2016-01-08T03:06:27.220

Reputation: 25 023

19

Bash + common utils, 51

seq 9$1|sed 13d\;/4/d\;1i-1|rs 0 2|sed $[$1/2]q|tac
  • seq generates ascending integers from 1 to N with an extra 9 digit in front - more than enough for 64bit integer input
  • sed filters out the unlucky floors and inserts -1 before line 1
  • rs reshapes into two tab-separated columns
  • sed stops after N/2 lines
  • tac reverses output line order

Digital Trauma

Posted 2016-01-08T03:06:27.220

Reputation: 64 644

I can shave 5 bytes for you - replace the sed $[$1/2]q after rs with sed $1q before it. I think that makes it POSIX-shell compatible, too. – Toby Speight – 2016-01-08T09:17:31.117

1Eventually, the preceding 1 won't be enough to compensate for passing only 0.9^n of the inputs through (numbers not containing 4 get sparser and sparser as the number of digits increases). But once you have more than a few hundred million floors in your hotel, you probably have other problems, such as keeping the plumbing working, and organising staff rotas. – Toby Speight – 2016-01-08T09:55:55.157

@TobySpeight you might have a space elevator too :) – Digital Trauma – 2016-01-08T16:21:10.467

@TobySpeight Even with the max signed 64bit integer as input (9223372036854775807), simply prefixing a 1 is (just about) enough - at least with my rudimentary base 9 calculation. The rest of the answer is limited to this range anyway due to the shell $[] arithmetic. I think this is a reasonable limitation in the absence of explicit mention of arbitrary precision arithmetic in the question. Regardless, I'm now prefixing a 9 instead of 1, just to be on the safe side. – Digital Trauma – 2016-01-08T21:20:13.380

10

JavaScript ES6, 236 234 233 210 195 188 bytes

Saved a whole bunch 'a bytes thanks to usandfriends!

Uses the function* for generators. Probably a shorter way to do this, but it was fun. Way fun. I'll bet some golfing can be done. Those weird whitespace things are tabs.

z=prompt(i=x=0,l=[]);y=(function*(){while(i<z-x)yield(i?(/4/.test(i)||i==13?--x&&".":i):-1)+(0*++i)})();while(a=y.next().value)+a&&l.push(a);l.join`    `.match(/-?\d+  \d+/g).reverse().join`
`

Conor O'Brien

Posted 2016-01-08T03:06:27.220

Reputation: 36 228

z=+prompt(i=x=0,l=[]); ==> z=prompt(i=x=0,l=[]); (-1 byte) – usandfriends – 2016-01-08T03:52:33.073

@usandfriends Thank you! I forgot about automatic type conversion. – Conor O'Brien – 2016-01-08T03:53:02.623

.join with tab and replace space in /-?\d+ \d+/g with tab, remove .map(x=>x.replace(/ /,"\t")) (should save 23 bytes) – usandfriends – 2016-01-08T04:01:29.810

@usandfriends And thanks again! – Conor O'Brien – 2016-01-08T04:03:56.650

For some reason, I seem to be getting a byte count of 210.

– usandfriends – 2016-01-08T04:07:14.343

@usandfriends That's weird, The length is 207 on my console... – Conor O'Brien – 2016-01-08T04:09:58.080

Shows 210 when I use this, this, and wc -c. Just curious, what command do you use to check file size?

– usandfriends – 2016-01-08T04:20:51.223

1.filter(x=>x!=".0") ==> .filter(x=>+x), (-5 bytes) – usandfriends – 2016-01-08T04:26:55.657

2^ Scratch that, just remove the whole .filter(..) part! Try l.push(a); ==> +a&&l.push(a); (-15 bytes) – usandfriends – 2016-01-08T04:31:44.283

@usandfriends Thank you so much for you golfs! :D – Conor O'Brien – 2016-01-08T11:43:17.020

7

C, 282 Bytes

int main(int r,char*v[]){int c=atoi(v[1]),a[c],b,E=1E9,g,i,t,o=t=g=(E)-2;while(i++<c){while(t>0){r=t%10;t=t/10;if(r==4||g==(E)+13||g<=o||g==E)t=++g;}a[i-1]=o=t=g;}for(c-=3;c>=0;c-=2){printf("%d\t",a[c+1]-E);printf("%d\n",a[c+2]-E);}printf("%d\t",a[0]-E);if(i%2)printf("%d",a[1]-E);}

Formatted :

int main ( int r , char * v[] ) {
    int c = atoi ( v[ 1 ] ) , a[c] , b , E = 1E9 , g , i , t , o = t = g = ( E ) - 2;
    while ( i ++ < c ) {
        while ( t > 0 ) {
            r = t % 10;
            t = t / 10;
            if ( r == 4 || g == ( E ) + 13 || g <= o || g == E )t = ++ g;
        }
        a[ i - 1 ] = o = t = g;
    }
    for ( c -= 3 ; c >= 0 ; c -= 2 ) {
        printf ( "%d\t" , a[ c + 1 ] - E );
        printf ( "%d\n" , a[ c + 2 ] - E );
    }
    printf ( "%d\t" , a[ 0 ] - E );
    if ( i % 2 )printf ( "%d" , a[ 1 ] - E );
}

Features :

It can compute up to 2095984 floors, if each floor is 19.5m high (incl. ceiling) then this building is long enough to be wrapped around the equator! 2095984*19.5=40871688m=~40000km=one 'lap' around the planet.

x13

Posted 2016-01-08T03:06:27.220

Reputation: 180

1

Nice answer, but your geography's a bit off. The distance from the equator to the north pole is 10000km by definition https://en.wikipedia.org/wiki/Metre which means the circumference of the equator is a little over 40000km.

– Level River St – 2016-01-08T23:46:37.250

1Nice comment, but your definition of the metre is a bit outdated. ;-) – murphy – 2016-01-09T01:18:12.610

@steveverrill i just used the first number i got off google, i'll update the calculation. – x13 – 2016-01-09T16:52:20.840

You can save a few bytes by dropping "int" from main. Are braces around E really necessary? First while can be converted to for and this allows you to drop some curly braces. t/=10 is a byte shorter than t=t/10. Add 1 to c in you for loop to save a couple bytes -> a[c+1] becomes a[c], while all other numbers have the same length. I'd also combine two printfs in the loop together, and dropped curly braces again. – aragaer – 2016-01-10T14:57:57.790

I think your definition of "floor height" might be a bit off - a typical floor is about 3m tall, not 19.5m tall. – nneonneo – 2016-01-10T23:33:09.683

@aragaer yes, you're right about the int, t/=10 and everything. Thank you. – x13 – 2016-01-11T08:41:33.343

@nneonneo if each floor is 19.5m, i didn´t say this was typical. I'll suggest you look at my edits. – x13 – 2016-01-11T08:43:18.677

6

Julia, 134 132 bytes

x=[-1;filter(i->i!=13&&'4'∉"$i",1:2(n=parse(readline())))][1:n]
for i=2:2:endof(x) println(join((r=reverse)(r(x)[i-1:i]),"  "))end

That funny whitespace in there is a literal tab. As Conor O'Brien noted, this is a byte shorter than doing \t.

Ungolfed:

# Read an integer from STDIN
n = parse(readline())

# Generate all numbers from 1 to 2n, exclude 0, 13, and all numbers containing 4,
# prepend -1, then take the first n
x = [-1; filter(i -> i != 13 && '4' ∉ "$i", 1:2n)][1:n]

# Loop over pairs, print tab-separated
for i = 2:2:endof(x)
    println(join(reverse(reverse(x)[i-1:i]), "  "))
end

Alex A.

Posted 2016-01-08T03:06:27.220

Reputation: 23 761

6

JavaScript, 116 122

Edit Saved 6 bytes thx @Neil

Simple array solution - not even using ES6

Try with any browser

/* test */ console.log=function(x){ O.innerHTML+=x+'\n'; }

n=prompt();for(r=[-1],v=1;n;v++)v!=13&!/4/.test(v)&&--n&&r.push(v);for(;r[0];)console.log(a=r.pop(b=r.pop())+'\t'+b)
<pre id=O></pre>

edc65

Posted 2016-01-08T03:06:27.220

Reputation: 31 086

You can save 6 bytes by using !/4/.test(v). – Neil – 2016-01-08T16:32:58.243

You could save a single byte with ' ' instead of '\t' (literal tab) – Mwr247 – 2016-01-13T07:42:06.123

6

Python 2, 120 110 bytes

N=input()
n=['-1']+[`i`for i in range(N*2)if i!=13and'4'not in`i`][1:N]
while n:x=n.pop();print n.pop()+'\t'+x

TFeld

Posted 2016-01-08T03:06:27.220

Reputation: 19 246

I think you can use i-13 instead of i!=13 – 12Me21 – 2019-01-18T23:20:48.380

6

Python 2, 94 bytes

n=input();c=-1;s=''
while n:
 if('4'in`c`)==0!=c!=13:n-=1;s=(n%2*'%d	%%d\n'+s)%c
 c+=1
print s

Try it online!

There's a tab character in the string that SE doesn't render (thanks to Sp3000 for suggested to use it, saving a byte).

Tests floors c starting from floor -1 until the quota n of floors is reached. For each floor, tests that it doesn't contain a 4 nor equals 0 or 13. If so, prepends it to the elevator string s and decrements the quota n.

A trick with string formatting is used to get the two floors per column to appear in the proper order when prepended. Each new line is prepared as '%d\t%%d\n', so that when two floors are substituted in order, the first is on the left and the second is on the right. For example,

('%d\t%%d\n'%2)%3 == ('2\t%d\n')%3 == '2\t3\n'  

xnor

Posted 2016-01-08T03:06:27.220

Reputation: 115 687

Pretty cool, but it's actually 96 bytes. Probably remove the trailing comma?

– movatica – 2019-05-02T20:54:47.263

2@movatica Good catch on the trailing comma, since the challenge specifies trailing newline is OK. The 1 byte difference was because the SE code block can't display tabs, so I put in a \t. Ah, the days before TIO existed. – xnor – 2019-05-03T22:02:07.693

5

Ruby 2.3, 84 83 characters

(82 characters code + 1 characters command line option)

puts (["-1",*?1..?1+$_].grep_v(/^13$|4/)[0..$_.to_i]*?\t).scan(/\S+\t\d+/).reverse

Sample run:

bash-4.3$ ruby -ne 'puts (["-1",*?1..?1+$_].grep_v(/^13$|4/)[0..$_.to_i]*?\t).scan(/\S+\t\d+/).reverse' <<< '14'
15      16
11      12
9       10
7       8
5       6
2       3
-1      1

Ruby, 93 92 characters

(91 characters code + 1 character command line option)

puts ([-1,*1..2*n=$_.to_i].reject{|i|i==13||i.to_s[?4]}[0..n]*?\t).scan(/\S+\t\d+/).reverse

Sample run:

bash-4.3$ ruby -ne 'puts ([-1,*1..2*n=$_.to_i].reject{|i|i==13||i.to_s[?4]}[0..n]*?\t).scan(/\S+\t\d+/).reverse' <<< '14'
15      16
11      12
9       10
7       8
5       6
2       3
-1      1

manatwork

Posted 2016-01-08T03:06:27.220

Reputation: 17 865

5

C#, 296 bytes

namespace System.Collections.Generic{using Linq;class X{static void Main(){var a=new List<int>();var b=new List<int>();for(int i=int.Parse(Console.ReadLine()),j=-2;i>0;)if(++j!=13&&j!=0&&!(j+"").Contains("4"))(i--%2<1?a:b).Insert(0,j);Console.Write(string.Join("\n",a.Zip(b,(x,y)=>x+"\t"+y)));}}}

Ungolfed:

namespace System.Collections.Generic
{
    using Linq;
    class X
    {
        static void Main()
        {
            var a = new List<int>();
            var b = new List<int>();
            for (int i = int.Parse(Console.ReadLine()), j = -2; i > 0;)
                if (++j != 13 && j != 0 && !(j + "").Contains("4"))
                    (i-- % 2 < 1 ? a : b).Insert(0, j);
            Console.Write(string.Join("\n", a.Zip(b, (x, y) => x + "\t" + y)));
        }
    }
}

Golfing tricks used:

  • i (the running counter) and j (the current number under consideration) are decremented/incremented, respectively, inside the expression in the loop body instead of the for statement as is normal
  • j+"" instead of j.ToString()
  • Place everything inside namespace System.Collections.Generic not only so that we can access List<T>, but also implicitly use the namespace System without further qualification
  • Place the using inside the namespace so that we can write using Linq; instead of using System.Linq;
  • .Insert(0,j) is shorter than using .Add(j) and later applying .Reverse()

It is unfortunate that the using Linq; is necessary, since it is needed only for .Zip, but writing it as Linq.Enumerable.Zip() is longer.

Timwi

Posted 2016-01-08T03:06:27.220

Reputation: 12 158

4

Lua, 169 Bytes

t={-1}i=1 repeat if(i..""):find("4")or i==13 then else table.insert(t,i)end i=i+1 until #t==arg[1] for i=#t%2==0 and#t-1 or#t,1,-2 do print(t[i],t[i+1]and t[i+1]or"")end

Fairly straight forward, we first assemble a table filled with all the button values. Then we iterate through it backwards, printing two values at a time, or nothing if the second value does not exist.

Nikolai97

Posted 2016-01-08T03:06:27.220

Reputation: 653

4

Mathematica, 105 bytes

StringRiffle[Reverse[Select[Range[2#]-2,#!=13&&#!=0&&DigitCount[#,10,4]<1&][[;;#]]~Partition~2],"
","\t"]&

Replace the \t with an actual tab character.

LegionMammal978

Posted 2016-01-08T03:06:27.220

Reputation: 15 731

4

Brachylog, 105 bytes

,Ll?,Lbb:1{h_.|[L:I]hhH,I+1=J((13;J:Zm4),L:J:1&.;Lb:J:1&:[J]c.)}:[1:-1]c{_|hJ,?bhw,[9:J]:"~c~w
"w,?bb:2&}

Would have been a lot shorter with CLPFD support, here I have to iteratively try integers in the first sub-predicate.

The new line before "w,?bb:2&} is mandatory, this is the new line that is printed between every row.

Fatalize

Posted 2016-01-08T03:06:27.220

Reputation: 32 976

Nice! One question: Why not make all integer arithmetic in Brachylog use CLP(FD) constraints automatically? This would be a natural logical extension. – mat – 2016-01-13T22:19:15.083

@mat because I'm lazy and I didn't. But I should! – Fatalize – 2016-01-14T08:55:12.373

That would be awesome! Built-in implicit CLP(FD) constraints for all integer arithmetic! Pave the future of declarative programming! "And it must seem blessedness to you to impress your hand on millennia as on wax. Blessedness to write on the will of millennia as on bronze--harder than bronze, nobler than bronze. Only the noblest is altogether hard." – mat – 2016-01-14T09:03:06.447

@mat Could you join me in this chat room to discuss this? I need advice from someone obviously more experienced with Prolog than me.

– Fatalize – 2016-01-14T09:09:31.763

3

05AB1E, 25 23 22 bytes

-1 byte thanks to @ASCII-only

·Ý<0K13Kʒ4å_}s£2ôR9çý»

Try it online!

Explanation

                           # Implicit input: integer n
·Ý<                        # Push list [-1,0,1,...,2n-1]
   0K                      # Remove 0 from [-1,0,1,...,2n-1]
     13K                   # Remove 13 from [-1,1,...,2n-1]
        ʒ4å_}              # Filter out every number containing a 4 from the list
             s£            # Pick out the n first element in the list
               2ôR         # Splice list into parts of length 2
                  9çý      # Join with tab character (ascii value 9)
                     »     # Join with newlines

Wisław

Posted 2016-01-08T03:06:27.220

Reputation: 554

122? – ASCII-only – 2019-01-19T00:47:21.990

Ah. I knew there was a way to make that ugly 0 13ª part a bit better. Thanks! – Wisław – 2019-01-19T00:51:35.400

wait. there's no logical and in 05AB1E? O_o – ASCII-only – 2019-01-19T00:54:20.323

1If 1 is true and 0 is false then multiplication works as logical and – Wisław – 2019-01-19T00:56:28.410

-1 byte by changing ʒ4å_} to 4мïê. PS: based on your earlier comment: 0 13ª could have been ¾13ª as well. – Kevin Cruijssen – 2019-05-03T12:49:50.563

3

C#, 277 343

using System;using System.Collections.Generic;static void f(int v){List<int>a=new List<int>();List<int>b=new List<int>();int s=1;for(int i=-1;i<v-1;i++){if(i==13||i.ToString().Contains("4")||i==0){ v++;continue;}if(s==1){s=2;a.Add(i);}else{s=1;b.Add(i);}}a.Reverse();b.Reverse();int l=0;foreach(int y in a){Console.WriteLine(y+" "+b[l]);l++;}}

This is as a function only. I'm new to C#. Increase was to make valid for 40-49, and for including usings

Ungolfed, as a complete running program:

using System;
using System.Collections.Generic;

class P {
    static void Main()
    {
        List<int> a = new List<int>();
        List<int> b = new List<int>();
        int v = Int32.Parse(Console.ReadLine());
        int s = 1;
        for (int i = -1; i < v - 1; i++)
        {
            if (i == 13 || i.ToString().Contains("4") || i == 0)
            {
                v++;
                continue;
            }
            if (s == 1)
            {
                s = 2;
                a.Add(i);
            }
            else {
                s = 1;
                b.Add(i);
            }
        }
        a.Reverse();
        b.Reverse();
        int l = 0;
        foreach (int y in a)
        {
            Console.WriteLine(y + " " + b[l]);
            l++;
        }
        Console.ReadLine();
    }
}

Explained

I create two lists, and alternate between pushing to them, reverse them, loop through one, and grab the other by index.

Goose

Posted 2016-01-08T03:06:27.220

Reputation: 219

I don't know much about C# but can't you replace if(s==1) by if(s) (automatic cast from int to boolean?) – Fatalize – 2016-01-08T16:01:42.363

Nah, because the else is for s == 2, although I could make the flag 0 and 1 instead of 1 and 2. I'll try that. – Goose – 2016-01-08T16:16:55.120

3

C++11, 259 258 203 202 195 194 bytes

Slashed off 1 byte, thanks to Conor O'Brien's idea to use literal tab instead of \t.

UPD 2: slashed off 55 bytes with improved logic and comma abuse.

UPD 3: another byte off thanks to ceilingcat.

UPD 4: 7 bytes off courtesy of ceilingcat.

UPD 5: and another byte off by ceilingcat.

Happy to have all includes in place AND still beat the C and C# solutions.

#include<iostream>
#include<string>
int main(){std::string o="-1    1",c,b;int n,i=2,s=2;for(std::cin>>n;s<n;o=i==14|~c.find(52)?o:(++s&1?b=c,"":b+'    '+c+'\n')+o)c=std::to_string(i++);std::cout<<o;}

Ungolfed:

#include <iostream>
#include <string>

int main()
{
    std::string o = "-1 1", c, b;
    int n, i = 2, s = 2;
    for (std::cin >> n;
         s < n;
         o = i == 14 | ~c.find(52) ? o : (++s & 1 ? b = c, "" : b + '   ' + c + '\n') + o
    )
        c = std::to_string(i++);
    std::cout << o;
}

Alexander Revo

Posted 2016-01-08T03:06:27.220

Reputation: 270

iostream includes string, so you can skip the second include for a big decrease in bytecount :) – movatica – 2019-05-02T21:09:41.943

@movatica Not according to cppreference.com, and compilation in VS2019 fails without it. So if it compiles somewhere else it's specific to that certain standard library implementation. – Alexander Revo – 2019-05-03T10:28:09.237

ok, seems to be a gcc thing. – movatica – 2019-05-03T11:36:34.380

191 bytes – ceilingcat – 2019-05-03T21:51:40.877

3

Python 3, 155 bytes

I think listifying, reversing, and self-zipping the floor-number generator s() may have been too clever for its own good, but others have already done the alternative (popping two items at a time), not to mention using Python 2 which saves bytes on some key points.

def s(m,n=-1):
 while m:
  if not(n in(0,13)or'4'in str(n)):yield n;m-=1
  n+=1
*f,=s(int(input()))
g=iter(f[::-1])
h=zip(g,g)
for a,b in h:print(b,'\t',a)

The shorter, but already-done-better alternative takes 140 bytes.

def s(m,n=-1):
 while m:
  if not(n in(0,13)or'4'in str(n)):yield n;m-=1
  n+=1
*f,=s(int(input()))
while f:a=f.pop();print(f.pop(),'\t',a)

Tim Pederick

Posted 2016-01-08T03:06:27.220

Reputation: 1 411

For the second alternative, (0!=n!=13)!=('4'in str(n)) is 5 bytes shorter than not(n in(0,13)or'4'in str(n)). – movatica – 2019-05-02T21:17:46.673

3

Japt, 42 bytes

JoU*2 k0 kD f@!Xs f4} ¯U ã f@Yv} w ®q'    } ·

The four spaces should be an actual tab char. Try it online!

How it works

          // Implicit: U = input integer, D = 13
JoU*2     // Create the range of integers [-1,U*2).
k0 kD     // Remove 0 and 13.
f@!Xs f4} // Filter out the items X where X.toString().match(/4/g) is not null, i.e. the numbers that contain a 4.
¯U ã      // Slice to the first U items, and generate all adjacent pairs of items.
f@Yv}     // Filter out the items where the index Y is odd. This discards every other pair.
w         // Reverse.
®q'\t}    // Join each item with tabs.
·         // Join the whole list with newlines.
          // Implicit: output last expression

ETHproductions

Posted 2016-01-08T03:06:27.220

Reputation: 47 880

3

Lua, 141 bytes

n,s=1,'-1 1'function g()repeat n=n+1 until s.find(n,4)==z and n~=13 return n end for i=4,io.read(),2 do s=g()..' '..g().."\n"..s end print(s)

Ungolfed

n,s = 1,'-1'1' --n is the current floor number, S is the string to be printed
function g() --This function raises n to the next valid floor
    repeat --Same as while loop except it runs the following block before checking the expression
        n = n + 1 --Self-explanatory, increases n by one
    until --Checks the expression, if it is true, it breaks out of the loop
        s.find(n,4) == z --[[Strings have a member :find(X) where it finds the position of
                             X in the string (X can also be a pattern). However, calling it 
                             by .find(S,X) executes find on S with argument X. I can't 
                             directly do n:find(4) because n is a number. This is a "hack" 
                             (sort of) to cut down some bytes. Also, if X is not a string,
                             lua tries to (in this case, succeeds) cast X to a
                             string and then look for it. I check if this is equal to z
                             because z is nil (because it is undefined), and find returns
                             nil if X is not found in S.
                             TL;DR: Checks if 4 is not the last digit.]]
        and n ~= 13 --Self-explanatory, checks if n is not 13
        return n --Self-explanatory, returns n
end
for i = 4, io.read(), 2 do --[[Start at floor 3 (shows 4 because we're going by target
                               floor, not by starting floor), continue until we reach
                               floor io.read() (io.read returns user input), increment by
                               2 floors per iteration)]]
    s = g() .. ' ' .. g() .. "\n" .. s --[[Prepend the next floor, a space, the next floor,
                               and a newline to s]]
end
print(s) --Self-explanatory, output the string

Try it online (you need to click 'execute' on the top and then click the terminal on the bottom before typing input; I'm looking for a better way to test lua online with stdin and stdout)

QuertyKeyboard

Posted 2016-01-08T03:06:27.220

Reputation: 71

2

Perl 6, 73 bytes

{.join("    ").say for (-1,|grep {$_-13&!/4/},1..Inf)[^$_].rotor(2).reverse}

Assumes an even number of floors, since the problem statement seems to assume it as well and at least one other provided solution breaks for odd numbers of floors. Just add ,:partial as a second argument to rotor, for nine more bytes, to support odd numbers of floors.

Sean

Posted 2016-01-08T03:06:27.220

Reputation: 4 136

55 bytes – Jo King – 2019-01-19T00:37:59.590

2

Jelly, 20 bytes

ḟ13D_4Ȧµ#o-s2Ṛj€9Ọ¤Y

Try it online!

How?

ḟ13D_4Ȧµ#o-s2Ṛj€9Ọ¤Y - Main Link: no arguments
        #            - start at n=0 and collect the first INPUT values which are truthy under:
       µ             -   the monad (i.e. f(n)):        e.g.:    0      3      4      13     42        813
ḟ13                  -     filter out thirteens                 [0]    [3]    [4]    []     [42]      [813]
   D                 -     convert to decimal lists             [[0]]  [[3]]  [[4]]  []     [[4,2]]   [[8,1,3]]
    _4               -     subtract four (vectorises)           [[-4]] [[-1]] [[0]]  []     [[0,-2]]  [[4,-3,-1]
      Ȧ              -     any & all?                           1      1      0      0      0         1
         o-          - logical OR with -1 (replace floor 0 with floor -1)
           s2        - split into twos
             Ṛ       - reverse
                  ¤  - nilad followed by link(s) as a nilad:
                9    -   literal nine
                 Ọ   -   to character (a tab)
              j€     - join €ach
                   Y - join with newlines
                     - implicit print

Jonathan Allan

Posted 2016-01-08T03:06:27.220

Reputation: 67 804

2

Java, 333 Bytes

import java.util.*;interface E{static void main(String[]a){byte i=-1;Stack<Byte>s=new Stack<>();while(s.size()<Byte.valueOf(a[0])){if(i==13|i==0|String.valueOf(i).contains("4")){i++;continue;}s.add(i);i++;}if(s.size()%2!=0){System.out.println(s.pop());}while(!s.isEmpty()){int r=s.pop();int l=s.pop();System.out.println(l+"\t"+r);}}}

Adds allowed floor numbers to a stack then pops them back off to print them.

I played around using an IntStream, but with all the imports this one ended up being smaller.

Brett C.

Posted 2016-01-08T03:06:27.220

Reputation: 21

2

Scala 147

val n=io.StdIn.readInt;(-1 to 4*n).filter(i=>i!=0&&i!=13&&(!(i+"").contains(52))).take(n).reverse.grouped(2).toList.map{i=>println(i(1)+"\t"+i(0))}

Nitin Nizhawan

Posted 2016-01-08T03:06:27.220

Reputation: 131

This is obviously the Scala'd down version. – CJ Dennis – 2016-01-11T12:52:54.407

2

PowerShell, 106 107 bytes

$c=,-1+$(while($i+1-lt"$args"){if(++$c-notmatch'^13$|4'){$c;++$i}})
while($c){$a,$b,$c=$c;$s="$a    $b
$s"}$s

Ungolfed

# Calculate floors:
$c=,-1 # Array with one element
  +
  $( # Result of subexpression
    while($i+1-lt"$args"){ # Uninitialized $i is 0, +1 ensures loop start from 1
      if(
        ++$c-match'^13$|4' # Expression increments uninitialized $c (i.e. start from 1)
                           # and matches resulting number to regex.
      ){
        $c;++$i # Return $c and increment $i counter 
      }
    }
  )

# Print floors:
while($c){ # Loop until no more elements in $c
  $a,$b,$c=$c # Use PS's multiple assignment feature
              # $a - first element of $c array
              # $b - second element of $c array
              # $c - the rest of elements of $c array
  $s="$a    $b
$s" # Create string with tabs and newlines,
    # literal characters are used
}
$s # Output resulting string

Example

PS > .\Elevator.ps1 14
15  16
11  12
9   10
7   8
5   6
2   3
-1  1

beatcracker

Posted 2016-01-08T03:06:27.220

Reputation: 379

2

Python 3, 117 Bytes

n=int(input())
l=[-1]+[i for i in range(n*2)if(i!=13)*(not'4'in str(i))][1:n]
while l:x=l.pop();print(l.pop(),'\t',x)

Modified version of the python 2 post to fit the python 3 specification.

Chiel ten Brinke

Posted 2016-01-08T03:06:27.220

Reputation: 201

2

Haskell 202 bytes

t=(-1):[x|x<-[1..],x/=13,all (/='4')(show x)]
by2 []=[[]]
by2 [a]=[[a]]
by2 [a,b]=[[a,b]]
by2 (a:b:xs)=[a,b]:(by2 xs)
main=do
 n<-getLine
 putStr$unlines$map unwords$by2$map show$reverse$take(read n) t

I’am haskell beginner…

  • first create the infinite list of values. (t list)
  • function by2 group a list into sublists of 2 elements.
  • main take the value.
    • take value elements of t list
    • reverse the list to have greaters elements first
    • map show function to convert int list to string list
    • group element 2 by 2 with by2 function
    • We have a list like [ ["4", "5"], ["6", "7"] ] transformed like [ "4 5", "6 7"] with unwords function mapped on list
    • unlines the list (each element of the list separate by '\n')
    • finish with putStrLn to write string on terminal.

Capello

Posted 2016-01-08T03:06:27.220

Reputation: 21

You can save several bytes in defining by2 by using a 1 character name and re-ordering: use your last line as is, then b x = [x] after. – ballesta25 – 2016-01-12T08:00:02.807

2

Javascript ES6 114 bytes

n=>[...Array(n)].map(_=>{while(/^13$|4|^0/.test(++i));return i;},i=-2).join`    `.match(/-?\d+  \d+/g).reverse().join`\n`

Usage

f=n=>[...Array(n)].map(_=>{while(/^13$|4|^0/.test(++i));return i;},i=-2).join`  `.match(/-?\d+  \d+/g).reverse().join`\n`

f(100);

Charlie Wynn

Posted 2016-01-08T03:06:27.220

Reputation: 696

1

R, 106 bytes

n=scan();x=-1:n^2;x=x[-grep(4,x)][-14][-2][n:1];cat(paste0(matrix(x,2,n/2)[2:1,],c("	","\n"),collapse=""))

Try it online!

Explanation: it starts with the vector of floors from \$-1\$ to \$n^2\$, which is more than enough in all my tests. Should that ever be insufficient, we could switch to \$n^3\$ or \$n^9\$. It then removes the unlucky floor numbers (as well as floor 0), converts to a 2-row matrix form and inverts the rows to get the numbers in correct order, then outputs in the desired format, recycling the vector c("\t","\n"). As suggested by Conor O'Brien, use a literal tab instead of \t for -1 byte.

n=scan();                                        # read number of floors n
x=-1:n^2;                                        # initial vector of numbers
x=x[-grep(4,x)]                                  # remove floors with a 4
               [-14]                             # remove floor 13
                    [-2]                         # remove floor 0
                        [n:1];                   # keep lowest n remaining floors, highest to lowest
cat(paste0( 
  matrix(x,2,n/2)                                # split vector of floors into 2 rows
                 [2:1,],                         # take row 2 then row 1
                        c("   ","\n"),           # separate integers with alternating tabs and newlines (uses recycling)
                                    collapse=""))

Robin Ryder

Posted 2016-01-08T03:06:27.220

Reputation: 6 625

1

JavaScript (ES6), 151 146

alert([for(a of Array((n=+prompt(i=0))*2).keys())if((i+=t=/4/.test(a)||a==13,!t&&a<n+i))a].reduce((a,b,j,r)=>j%2-1?(b||-1)+`  ${r[j+1]}
`+a:a,''))

Did this before I realized edc65 had already made a shorter one. Oh well!

Mwr247

Posted 2016-01-08T03:06:27.220

Reputation: 3 494

0

APL (Dyalog), 34 bytes

{⊖(⍵÷2)2⍴o/⍨~'4'∊¨⍕¨o←13~⍨¯1,⍳⍵×⍵}

Try it online!

Uriel

Posted 2016-01-08T03:06:27.220

Reputation: 11 708

0

Perl 5 -MList::Util=pairmap -n, 62 bytes

pairmap{say"$b	$a"}reverse((-1,grep!/^13$|4/,1..121)[0..$_-1])

Try it online!

Xcali

Posted 2016-01-08T03:06:27.220

Reputation: 7 671