Goodness Giza Golf!

41

3

A "Giza number", also colloquially known as a Timmy Number is any number where the digits represent a pyramid (A134810). For example, "12321" is a giza number because it can be visualized like this:

  3  
 2 2
1   1

However, something like "123321" is not a Giza number because there are two digits at the top of the pyramid

  33  
 2  2
1    1

In other words, a number is a Giza number if all of the following conditions are met:

  • It has an odd number of digits, and the center digit is the largest

  • It's palindromic (the same read forwards or backwards), and

  • The first half of the digits are strictly increasing by one. (Since it must be palindromic, this means the second half of the digits must be strictly decreasing by one)

You must write a full program or a function that takes a positive integer as input, and determine if it is a Giza number or not. You may take the input as a string or as a number. If it is a Giza number, output a truthy value. Otherwise, a falsy value.

There are a total of 45 Giza numbers, so any one of these inputs should result in a truthy value:

1
2
3
4
5
6
7
8
9
121
232
343
454
565
676
787
898
12321
23432
34543
45654
56765
67876
78987
1234321
2345432
3456543
4567654
5678765
6789876
123454321
234565432
345676543
456787654
567898765
12345654321
23456765432
34567876543
45678987654
1234567654321
2345678765432
3456789876543
123456787654321
234567898765432
12345678987654321

Any other input should give a falsy value. Of course, you do not have to handle invalid inputs, such as non-positive numbers, non-integers, or non-numbers.

As usual, this is , so standard loopholes are banned, and the shortest answer in bytes wins!

James

Posted 2016-11-16T16:41:07.030

Reputation: 54 537

what about 0? is that a thruthy? – tuskiomi – 2016-11-16T16:48:24.050

@tuskiomi Technically, no, but it's irrelevant because you do not have to handle non-positive numbers. – James – 2016-11-16T16:49:12.863

1The reason I ask is because if it is a giza number, then numbers like 1210, 123210, etc would also be truthy. – tuskiomi – 2016-11-16T16:50:46.200

5@tuskiomi Neither of those are palindromic or have an odd number of digits. Unless you're counting a leading 0 but that makes everything way more complicated. – James – 2016-11-16T16:56:40.683

Is 0787 truthy? Or should we not ignore the leading zero? – nedla2004 – 2016-11-16T21:31:26.440

1@nedla2004 I think leading 0's makes input formats more complicated. To keep everything nice and simple, we'll say you can assume that inputs will not contain leading 0's. – James – 2016-11-17T20:44:44.860

Answers

30

Python 2, 48 47 46 bytes

lambda s:s[~len(s)/2:]in'987654321'>s==s[::-1]

Test it on Ideone.

How it works

In Python, a chained comparison returns True if and only if all individual comparison do the same. In this specific case, our lambda returns True if and only if all of the following conditions are met.

  • s[~len(s)/2:]in'987654321'

    For a string s of length 2n + 1, ~len(s)/2 returns ~(2n + 1) / 2 = -(2n + 2) / 2 = -(n + 1), so s[~len(s)/2:] yields the rightmost n + 1 characters of s.

    Similarly, for a string s of length 2n, ~len(s)/2 returns ~(2n) / 2 = -(2n + 1) / 2 = -(n + 1) (integer division always round towards -∞, so s[~len(s)/2:] once more yields the rightmost n + 1 characters of s

    The comparison returns True if and only if the rightmost n + 1 characters form a substring of 987654321.

    Note that if they do and s has 2n characters, s cannot be a palindrome; the nth and (n+1)th characters from the right will be distinct, and the latter is the nth character from the left.

  • '987654321'>s

    This compares the strings lexicographically. Since 9 is the only Giza number that starts with 9, all Giza numbers satisfy this comparison.

    Note that comparing these strings does not form part of our decision problem; >s is simply three characters shorter than and s.

  • s==s[::-1]

    This returns True if and only if s is a palindrome.

Dennis

Posted 2016-11-16T16:41:07.030

Reputation: 196 637

8This answer is insane wizardry. I understand how bits and pieces of it work, but can't even begin to comprehend how you came up with it. And for a moment there, I was proud of my 64. +1 – James – 2016-11-16T20:26:45.007

2i love the guaranteed comparison to save those 3 bytes – greyShift – 2016-11-17T22:12:20.023

22

Perl, 39 37 42 39 + 1 = 40 bytes

Using a new method, I managed to cut down a huge number of bytes. Run with the -n flag. Accepts input repeatedly at runtime, printing 0 or 1 accordingly.

I had to add 5 bytes because I realized without it, the code worked for inputs such as 1234567900987654321, which is not a Giza number. Since Giza numbers never contain the digit 0 (and all false positives by necessity would contain the digit 0), these 5 bytes account for that.

say!/0/*($_- s/..?/1/gr**2)=~/^(.)\1*$/

Explanation:

say!/0/*($_- s/..?/1/gr**2)=~/^(.)\1*$/  #$_ contains input by default.
   !/0/                                  #Ensure that the initial text doesn't contain the number 0
       *                                 #Since both halves of this line return either 0 or 1, multiplying them together only yields 1 if both are true (which we want).
             s/   / /gr                  #Perform a substitution regex on $_ (see below)
                                         #/g means keep replacing, /r means don't modify original string; return the result instead
               ..?                       #Replace 1 or 2 characters (2, if possible)...
                   1                     #...with the number 1
                       **2               #Square this number...
        ($_-              )              #...and subtract it from the input
                           =~            #Do a regex match on the result
                             /^      $/  #Make sure the regex matches the WHOLE string
                               (.)       #Match any character...
                                  \1*    #...followed by itself 0 or more times
say                                      #Finally, output the result of the whole line of code.

The purpose of the substitution regex is to construct a string of 1s whose length is half the length of the input, rounded up. Thus, an input of 12321 will produce the string 111, which then gets squared (explanation below). Even-length inputs will produce strings that are too small to ensure the final regex is successful.

The reason this code works is because of the following:

        1         =         1**2
       121        =        11**2
      12321       =       111**2
     1234321      =      1111**2
    123454321     =     11111**2
   12345654321    =    111111**2
  1234567654321   =   1111111**2
 123456787654321  =  11111111**2
12345678987654321 = 111111111**2

We can clearly see that the number of 1's in RHS is equal to 1/2 more than half the size of LHS. (1 more if we truncate). Additionally:

567898765 - 123454321 = 444444444, which is just 4 repeating. So when we subtract our square from our number, if we get a repdigit, our original number is a Giza number.

Old code and old method (58 + 1 = 59 bytes)

Saved 1 byte thanks to @Dada

Run with the -n flag, pipe text in using echo

say$_==($;=join"",/(.)/..($==y///c/2+/(.)/)-1).$=.reverse$

Calculates the unique giza number determined by the length and the leading integer, and sees if it matches the input.

Run as echo -n "123454321" | perl -M5.010 -n giza.pl Returns 1 if it's a Giza number, null otherwise.

Gabriel Benamy

Posted 2016-11-16T16:41:07.030

Reputation: 2 827

2That's a beautiful observation for the second method. – trichoplax – 2016-11-17T23:20:54.427

15

Jelly, 10 7 6 bytes

9ẆŒBḌċ

Generates all 45 Giza numbers numbers, then tests for membership.

Try it online! or see the generated numbers.

How it works

9ẆŒBḌċ  Main link. Argument: n

9       Set the return value to 9.
 Ẇ      Windows; yield all "substrings" of [1, ..., 9].
  ŒB    Bounce; map each [a, ..., b] to [a, ..., b, ..., a].
    Ḍ   Undecimal; convert the digit arrays to integers.
     ċ  Count the number of occurrences of n.

Dennis

Posted 2016-11-16T16:41:07.030

Reputation: 196 637

10

Java 7, 128 119 105 bytes

boolean t(long n){long a=1,b=1,c=0;for(;a<n/10;b=b*b<=n/10?b*10+1:b,c^=1)a=a*10+1;return(n-b*b)%a<1&c<1;}

No more strings! So, now I start by generating a 111... number of the same length as input (a), and one shorter to square (b). Then you can subtract b*b from the input and check divisibility by a. c is just there to check odd/even, pay it no mind >_>

Whitespaced:

boolean t(long n){
    long a=1,b=1,c=0;
    for(;a<n/10;b=b*b<=n/10?b*10+1:b,c^=1)
        a=a*10+1;
    return(n-b*b)%a<1&c<1;
}

Old Method, 119 bytes

boolean g(char[]a){int i=1,l=a.length,b=1,d;for(;i<l;b*=i++>l/2?d==-1?1:0:d==1?1:0)d=a[i]-a[i-1];return b>0?l%2>0:0>1;}

Walks through the array, checking for a difference of 1 (or -1, depending on which half) between each digit. Then just checks to see the length is odd.

Whitespaced:

boolean g(char[]a){
    int i=1,l=a.length,b=1,d;
    for(;i<l;b*=i++>l/2?d==-1?1:0:d==1?1:0)
        d=a[i]-a[i-1];
    return b>0?l%2>0:0>1;
}

Geobits

Posted 2016-11-16T16:41:07.030

Reputation: 19 061

Why do you need to check to see if the first is the same as the last? – Nathan Merrill – 2016-11-16T16:50:13.537

3I have no idea what you mean >_> – Geobits – 2016-11-16T17:04:06.007

Is this a valid answer considering the problem specifies that the function must take a positive integer? Of course a char array can represent a positive integer, but I think it's an important distinction. – Hypino – 2016-11-16T17:32:35.410

1

@Hypino The problem says input can be taken as a string or integer, and char[] counts as a string here, so I'd say it's valid.

– Geobits – 2016-11-16T17:37:16.183

@Geobits Ah I did miss the part where it said it could be taken as a String. – Hypino – 2016-11-16T17:42:07.247

Can you compile it to the equivalent of C#'s Func<long, bool> to save bytes or is that a JavaScript thing? I don't really know Java or JavaScript... – TheLethalCoder – 2016-11-17T12:03:59.337

Gotcha by 3 now ;) – Yodle – 2016-11-17T14:50:51.990

You can use an lambda func like n->{...} or use int as return type and apply ?1:0 to the return. – Roman Gräf – 2016-11-19T08:19:53.287

@Roman No lambdas in Java 7, and the int thing isn't considered a truthy return here for Java. – Geobits – 2016-11-19T15:52:43.267

10

JavaScript (ES6), 46 45 42 41 bytes

f=([c,...s])=>s+s&&c-s.pop()|c-~-f(s)?0:c

Takes input as a string and returns a single-digit string for truthy, 0 for falsy.

The basic idea is to check for a few things:

  • If the string is one char long, OR
  • the first char is the same as the last char, and
  • the middle section is also a Giza number, and
  • the second char is one more than the first char here.

ETHproductions

Posted 2016-11-16T16:41:07.030

Reputation: 47 880

Sorry, I misread the question. – Neil – 2016-11-16T20:31:42.700

6

PowerShell v3+, 147 108 67 bytes

$args[0]-in(1..9+(1..8|%{$i=$_;++$_..9|%{-join($i..$_+--$_..$i)}}))

Radically changed approach. Generates all possible Giza numbers, and then checks whether the input $args[0] is -in that collection. Below is how the collection of Giza numbers is formed:

1..9+(1..8|%{$i=$_;++$_..9|%{-join($i..$_+--$_..$i)}})
      1..8|%{                                       }  # Loop from 1 up to 8
             $i=$_;                                    # Set $i to the current number
                   ++$_..9|%{                      }   # Loop from one higher up to 9
                                   $i..$_+--$_..$i     # Build two ranges and concatenate
                                                       # E.g., 2..5 + 4..2
                             -join(               )    # Join into a single string
1..9+(                                               ) # Array concatenate with 1 to 9

Example runs:

PS C:\Tools\Scripts\golfing> 12321,5678765,121,4,123321,1232,5678,13631|%{"$_ --> "+(.\giza-numbers.ps1 "$_")}
12321 --> True
5678765 --> True
121 --> True
4 --> True
123321 --> False
1232 --> False
5678 --> False
13631 --> False

AdmBorkBork

Posted 2016-11-16T16:41:07.030

Reputation: 41 581

108 -> 67... looks like you win this time (and probably most of the time) :P – Yodle – 2016-11-17T14:51:29.693

6

05AB1E, 9 8 bytes

Truthy is 1, falsy is 0.

9LŒ€ûJ¹å

Uses the CP-1252 encoding. Try it online!

Adnan

Posted 2016-11-16T16:41:07.030

Reputation: 41 965

I think that 2ä¬û¹Q would work as well and saves two bytes. – Osable – 2016-11-17T09:57:39.317

@Osable 12521 isn't a giza number, this fails for the middle element. – Magic Octopus Urn – 2016-11-17T14:36:57.480

I realize now that i skipped the third point (consecutive digits). Nevermind! – Osable – 2016-11-17T14:41:28.747

Ahhhh... I was using prefixes, I'll keep substrings in mind for future efforts, neat little hack. – Magic Octopus Urn – 2016-11-17T14:43:57.097

6

Python 2, 77, 76, 64, 63 bytes

f=lambda s:2>len(s)or(s[0]==s[-1]==`int(s[1])-1`and f(s[1:-1]))

A simple recursive solution. Checks to see if the first and last digits equal each other and the second digit minus one. Then checks if the middle is also a Giza number. Returns true once it gets down to a single digit.

One byte saved thanks to @Rod, a ton of bytes saved thanks to DLosc and ETHProductions!

James

Posted 2016-11-16T16:41:07.030

Reputation: 54 537

you can swap len(s)==1 with 1==len(s) to save 1 byte on the space, also, the ands could be replaced with * to save 3 bytes – Rod – 2016-11-16T17:48:42.563

Just to add to Rod's comment: 1or works too. (As long as it's not a 0 preceding the o--then Python thinks it's an octal number.) – DLosc – 2016-11-16T17:49:51.193

@Rod Ooh, good idea. I thought the same thing about *, but that throws some weird indexing errors with even length strings. Not sure why – James – 2016-11-16T17:50:06.887

1You generally can't replace and with * when short-circuiting behavior is required, as it is in a recursive function. The first and should be replaceable, but it needs two sets of parentheses, which negates any savings. (cc: @Rod) – DLosc – 2016-11-16T17:53:33.433

1I don't know much Python, but could you 1) remove the int() around s[0] or 2) use s[0]==`int(s[1])-1`? – ETHproductions – 2016-11-16T17:55:48.290

1Building on @ETHproductions suggestion: s[-1]==s[0]==\int(s[1])-1`` (requires Python 2 specifically). – DLosc – 2016-11-16T17:57:37.300

@DLosc That's genius. Thanks! – James – 2016-11-16T17:59:49.113

One more byte, since empty string is an invalid input ("non-number"): 2>len(s). (Originally thought this wouldn't work because of the recursive case, but the s[1] check prevents the recursion from ever getting down to an empty string.) – DLosc – 2016-11-16T18:09:54.680

5

Python 2, 68 73 66 bytes

lambda n:n==`int('1'+len(n)/2%9*'1')**2+int(len(n)*`int(n[0])-1`)`

abusing the fact that 11^2=121, 111^2=12321 and so on, I calculate this and add 1111.. enough times as offset.
Examples:
23432=111^2+11111*1
676=11^2+111*5

Rod

Posted 2016-11-16T16:41:07.030

Reputation: 17 588

Since you are not calling f, you don't need to actually name it. You can save two bytes by removing f= – James – 2016-11-16T17:34:18.153

You should set a cap on this. Input 1234567900987654321 returns true, when it should be false. – Geobits – 2016-11-16T17:44:11.257

@Geobits ooops, fixed (I guess?) – Rod – 2016-11-16T18:03:32.507

5

Python 3, 65 bytes

lambda x:len(x)<18and x[:len(x)//2+1]in'0123456789'and x[::-1]==x

I'm not entirely sure, but I think this works.

0WJYxW9FMN

Posted 2016-11-16T16:41:07.030

Reputation: 2 663

1There are no Giza numbers that start with 0, you can remove that :) There also won't be any numbers longer than 17 that satisfy that condition so you don't need that either. It's essentially the same solution Dennis has :) – Kade – 2016-11-17T19:23:20.973

@Shebang but this one was posted first... – Rod – 2016-11-18T18:06:59.193

@Rod I wasn't claiming he copied or anything :) – Kade – 2016-11-18T18:24:26.860

@Shebang Neither am I c: – Rod – 2016-11-18T18:31:56.557

4

Perl, 41 bytes

40 bytes of code + -p flags.

s/(.)(?=(.))/$1-$2/ge;$_=/^(-1(?1)1|).$/

Outputs 1 if the input is a Giza number, nothing otherwise. Supply the input without final newline to run it :

echo -n '123456787654321' | perl -pe 's/(.)(?=(.))/$1-$2/ge;$_=/^(-1(?1)1|).$/'

Explanations : first, s/(.)(?=(.))/$1-$2/ge replace each digit $1 (followed by $2) by $1-$2. If it's a Giza number, then each digits being one less than the next in the beginning, and one more in the end, then the string should contain only -1 in the first part, and 1 in the second (except the last that is left unchanged). That's what the second part /^(-1(?1)1|).$/ checks : looks for a -1 followed by recursion followed by a 1.

-1 byte thanks to Martin Ender.


My previous version 15 bytes longer (quite different so I'll let it here) :

echo -n '123456787654321' | perl -F -pe '$\=$_ eq reverse;$\&=$F[$_-1]+1==$F[$_]for 1..@F/2}{'

Dada

Posted 2016-11-16T16:41:07.030

Reputation: 8 279

The only part of this I don't understand is the purpose of the | in the second regex. – Gabriel Benamy – 2016-11-16T19:19:15.687

@GabrielBenamy That's the base case of the recursive block (ie. it matches nothing and stops the recursion). – Dada – 2016-11-16T19:47:22.273

3

C#, 120 86 108 102 92 bytes

x=I=>{var Z=I.Length;return Z<2?1>0:I[0]==I[Z-1]&I[1]-0==I[0]+1?x(I.Substring(1,Z-2)):0>1;};

Full program with some test cases:

class a
{
    static void Main()
    {
        Func<string, bool> x = null;

        x = I=>
        {
            var Z=I.Length;
            return Z==1?                           // length == 1?
                     1>0:                          // return true (middle of #)
                     I[0]==I[Z-1]&I[1]-0==I[0]+1?  // else start == end and the next number is 1 above the current?
                       x(I.Substring(1,Z-2)):      // recursive call on middle
                       0>1;                        // else false
        };

        Console.WriteLine("1 -> " + (x("1") == true));
        Console.WriteLine("9 -> " + (x("9") == true));
        Console.WriteLine("121 -> " + (x("121") == true));
        Console.WriteLine("12321 -> " + (x("12321") == true));
        Console.WriteLine("4567654 -> " + (x("4567654") == true));
        Console.WriteLine("12345678987654321 -> " + (x("12345678987654321") == true));
        Console.WriteLine("12 -> " + (x("12") == false));
        Console.WriteLine("1221 -> " + (x("1221") == false));
        Console.WriteLine("16436346 -> " + (x("16436346") == false));
        Console.WriteLine("123321 -> " + (x("123321") == false));
        Console.WriteLine("3454321 -> " + (x("3454321") == false));
        Console.WriteLine("13631 -> " + (x("13631") == false));
        Console.WriteLine("191 -> " + (x("13631") == false));
        Console.Read(); // For Visual Studio
    }
}

Hooray for single line conditionals, now beating the Java answer :)! Also got to write my first explaining comments, though it's probably self explanatory. Thanks to @Dada for finding a problem with my algorithm (was true for numbers that were mirrored like 13631). Now sub 100 since apparently checking for length%2 is redundant.

Yodle

Posted 2016-11-16T16:41:07.030

Reputation: 2 378

1Wouldn't this return true for numbers like 13631 ? Also since you make a recursive call to x, I think you need to include x= in your byte count. – Dada – 2016-11-16T20:00:37.273

@Dada Heh good point, knew I was missing something... And alright, I'll add those to the count. – Yodle – 2016-11-16T20:01:49.593

Wait, you're beating what now? ;) – Geobits – 2016-11-17T02:14:57.817

@Geobits Dangit! I'll see what I can do tomorrow :P – Yodle – 2016-11-17T02:43:21.587

3

><> FISH 57 52 49 48 bytes

i:1+?!vi00.;n1<
%?v0n;>~l:1-?!^2
{:<11 ^?:=@:$+=

Edit 1: = returns 0 or 1 if true so removed a check and used this value to increment, then it checks equality after anyway. (saved 6 bytes, lost 1 for new line).

Edit 2: 3 directional markers removed and 11 placed into gap to offset the stack to an even length to force false ( 3 bytes saved).,

Edit 3: Duplicate the length of the stack for checking MOD by 2 and len(1), this was done by putting the length on twice before but this now filled an empty space on line 2 ( 1 byte saved).

Teal pelican

Posted 2016-11-16T16:41:07.030

Reputation: 1 338

3

Bash, 111 bytes

UPDATE

Note that input number normalization can probably be skipped completely, if you just add the first digit back to your generated GIZA number, like that:

01210 + 6 => 67876

and then just compare it with the input directly.

Disclaimer: this one is not really optimized, so it is more a proof of concept than a real contender

Golfed

G() { I=`sed "s/./\0-${1::1}\n/g"<<<$1|bc`;Z=`seq 0 $((${#1}/2))`;A=`rev <<<$Z`;cmp -s <(echo $I) <<<$Z${A:1}

Algorithm

Any GIZA number can be normalized to its canonical form, by substracting its first digit from the rest:

67876 - 6 => 01210
78987 - 7 => 01210

and there is only one canonical GIZA number of a particular length.

Knowing this we can easily generate a canonical GIZA number based on the input number length:

 Z=`seq 0 $((${#1}/2))`;A=`rev <<<$Z` => $Z${A:1}

then normalize the input number:

 I=`sed "s/./\0-${1::1}\n/g"<<<$1|bc`

and compare

 cmp -s <(echo $I) <<<$Z${A:1};

Test

for i in `seq 0 1000`; do G $i && echo $i; done

0
1
2
3
4
5
6
7
8
9    
121
232
343
454
565
676
787
898

...

G 12345678987654321 && echo "OK" || echo FALSE     
OK

G 123456789987654321 && echo "OK" || echo FALSE
FALSE

zeppelin

Posted 2016-11-16T16:41:07.030

Reputation: 7 884

I hope you don't mind, I implemented a part of this algorithm in my answer :)

– FlipTack – 2016-11-18T10:42:51.097

1

Retina, 55 54 36 bytes

Byte count assumes ISO 8859-1 encoding.

.
$*1:
+`^(1+:)(1\1.*)\b\1$
$2
^1+:$

Try it online

Convert each digit to unary, separated by colons. Loop, removing matching outer digits if the next digit is one more. Match a single remaining digit.

mbomb007

Posted 2016-11-16T16:41:07.030

Reputation: 21 944

1This accepts 12312 – Martin Ender – 2016-11-17T08:19:45.120

This works in 36 bytes. – Martin Ender – 2016-11-17T08:22:07.313

1

Octave, 56 bytes

@(n)nnz(n)<2||~(abs(diff(+n))-1)&&diff(+n(1:1+end/2))==1

Check out all test cases here.

This would be two less bytes in MATLAB, since diff(n) works for strings. In Octave, you need diff(+n).

Explanation:

@(n)                  % Anonymous function taking a string `n` as argument
    nnz(n)<2          % True if there is only one element in n
            ||        % Short circuit or operator. Expression will be true if this is true
~(abs(diff(+n))-1)    % Takes the absolute value of the difference between adjacent numbers
                      % which should always be 1. Subtracts 1, to get 0
                      % and negates it to get 1 (true)
diff(+n(1:1+end/2))==1   % Checks if the difference between the first half of the numbers
                         % is 1.
                      % If either the first, or both the second and third argument is true
                      % then the function will return 1, otherwise 0. 

Stewie Griffin

Posted 2016-11-16T16:41:07.030

Reputation: 43 471

1

Actually, 22 bytes

9uR;∙`xR;RdX+εj`M;░#íu

Try it online!

Takes input as a quoted string (e.g. "12321"). Output is a positive integer for true, and 0 for false.

Explanation:

9uR;∙`xR;RdX+εj`M;░#íu
9uR;∙                   cartesian product of [1,2,3,4,5,6,7,8,9,10] with itself
     `xR;RdX+εj`M       for each pair:
      x                   construct the half-open (end-exclusive) range ([1, 5] -> [1, 2, 3, 4])
       R                  reverse
        ;RdX+             duplicate, reverse, remove first element, prepend ([1, 2, 3, 4] -> [1, 2, 3, 4, 3, 2, 1])
             εj           concatenate into a string
                 ;░     filter out empty strings
                   #íu  test for membership

Mego

Posted 2016-11-16T16:41:07.030

Reputation: 32 998

1

Haskell, 62 bytes

(`elem`[[j..pred i]++[i,pred i..j]|i<-['1'..'9'],j<-['1'..i]])

The input is taken as a string.

Creates a list of all Giza numbers an checks if the number is in it. The list is created by looping i through '1'..'9' and then j through '1'..i and creating the elements j .. i-1 , i , i-1 .. j.

nimi

Posted 2016-11-16T16:41:07.030

Reputation: 34 639

1

Java 7, 129 119 109 bytes

boolean e(char[]a){int l=a[0]-1,f=0,b=a.length-1;for(;f<b&&a[f]==++l&a[f++]==a[b--];);return f==b&l==a[b]-1;}

Old Recursive Method, 119

boolean b(char[]a){int b=a.length;return b>1&&a[0]==a[b-1]&a[0]+1==a[1]?b(java.util.Arrays.copyOfRange(a,1,b-1)):b==1;}

-10 bytes thanks to Geobits. We are were tied...

Try it online!

Poke

Posted 2016-11-16T16:41:07.030

Reputation: 3 075

I think you could save 1 byte with bitwise and, I think you used it once but didn't the other time? Or I'm reading it wrong. – Yodle – 2016-11-16T20:58:57.420

@Yodle I only used it once because I need to short circuit for the first condition. – Poke – 2016-11-16T21:00:18.833

1It looks like you're only using the import once, so you should be able to shorten this by using java.util.Arrays.copyOfRange(...) to skip the import line. – Geobits – 2016-11-17T02:23:32.300

@Geobits good catch... I derp – Poke – 2016-11-17T14:13:07.507

1

Mathematica, 62 61 60 bytes

Saved 2 bytes due to @MartinEnder.

MatchQ[{a:1...,b___}/;{b}==-{a}]@*Differences@*IntegerDigits

Composition of functions. Takes a number as input and returns True or False as output.

LegionMammal978

Posted 2016-11-16T16:41:07.030

Reputation: 15 731

1

><>, 62 bytes

i:0(   ?v
v!1&!~{!<:=$:@&-1=+2=*>l!-3!1(!:?
>l!;2!n=!0?!<-1=n;

Try it online!

Outputs 1 for a Giza number; 0 otherwise. Works by pushing the input into a dequeue (ok, technically a reversible stack) and repeatedly testing both ends for equality, as well as making sure they are exactly one larger than the previous value.

Brian Gradin

Posted 2016-11-16T16:41:07.030

Reputation: 569

1

CJam, 20 19 bytes

l_$_W=),\ci>_W<W%+=

Test suite.

Explanation

The basic idea is to find the minimum and maximum digit, then create a Giza number from those and then check that it's equivalent to the input.

l       e# Read input.
_$      e# Get a sorted copy of the input.
_W=     e# Get its last character, i.e. the maximum digit M.
),      e# Get a string with all characters from the null byte up to M.
\c      e# Get the first character of the sorted string, i.e. the minimum
        e# character m.
i>      e# Convert to its character code and discard that many leading
        e# characters from the string we generated before. Now we've got
        e# a string with all digits from m to M, inclusive.
_W<W%+  e# Palindromise it, by appending a reversed copy without M.
=       e# Check that it's equal to the input.

Instead of the minimum character, we can also use the first character, for the same byte count:

l_:e>),1$ci>_W<W%+=

Martin Ender

Posted 2016-11-16T16:41:07.030

Reputation: 184 808

1

PHP, 71 bytes

for($t=$i=max(str_split($s=$argv[1]));$t!=$s&&--$i;)$t="$i$t$i";echo$i;

fetches the largest digit from input and counts down, adding the new digit to a comparison string until input and comparison string are equal - or $i is 0.

prints the lowest digit for a Timmy Number, 0 else.

Titus

Posted 2016-11-16T16:41:07.030

Reputation: 13 814

1

Pushy, 30 15 bytes

I woke up this morning and realise I could half the length of my answer...

s&K-kL2/OvhXwx#

(non-competing as the language postdates challenge)

Input is given on the command line: $ pushy gizas.pshy 3456543. Outputs 1 for truthy and 0 for falsy. Here's the breakdown:

s                  % Split the number into its individual digits
 &K-               % Subtract all digits by the last 
    kL2/  h        % Get the halved length of the stack (+1)
        Ov X       % In stack 2, generate range (0, halved length)
            w      % Mirror the range 
             x#    % Check stack equality and output

The algorithm was inspired by the bash answer: first, normalize the number, (45654 -> 01210), then generate the normalized giza number of the same length (there is only one), and compare.


Old Solution

s&K-Y?kL2%?L2/:.;&OvhXx#i;;;0#

FlipTack

Posted 2016-11-16T16:41:07.030

Reputation: 13 242

1

Mathematica, 56 bytes

This is a little shorter:

MatchQ[Differences@IntegerDigits@#,{a:1...,b__}/;b==-a]&

Kelly Lowder

Posted 2016-11-16T16:41:07.030

Reputation: 3 225

1

Racket 292 bytes

(let*((s(number->string n))(sn string->number)(st string)(lr list-ref)(sl(string->list s))(g(λ(i)(-(sn(st(lr sl(add1 i))))
(sn(st(lr sl i)))))))(cond[(even?(string-length s))#f][(not(equal? s(list->string(reverse sl))))#f][(andmap identity
(for/list((i(floor(/(length sl)2))))(= 1(g i))))]))

Ungolfed:

(define(f n)
  (let* ((s (number->string n))
         (sn string->number)
         (st string)
         (lr list-ref)
         (sl (string->list s))
         (g (λ (i) (- (sn(st(lr sl (add1 i))))
                      (sn(st(lr sl i)))))))
    (cond
      [(even? (string-length s))
       #f]
      [(not(equal? s (list->string (reverse sl))))
       #f]
      [else
       (andmap identity
               (for/list ((i (floor(/(length sl)2))))
                 (= 1 (g i))))]
      )))

Testing:

(f 12321) 
(f 123321)  ; only this should be false; 

(f 9)
(f 787)
(f 67876)
(f 4567654)
(f 123454321)
(f 12345654321)
(f 1234567654321)
(f 123456787654321)
(f 12345678987654321)

Output:

#t
#f
#t
#t
#t
#t
#t
#t
#t
#t
#t

rnso

Posted 2016-11-16T16:41:07.030

Reputation: 1 635

1

Java 8, 162 + 19 bytes

19 for import java.util.*;

s->{List f=new ArrayList();for(int i=0;i<9;){String l=String.valueOf(++i);for(int j=i;j>0;){f.add(l);String k=String.valueOf(--j);l=k+l+k;}}return f.contains(s);}

Different approach to the other Java answer, I wanted to try and use the method of creating all the possible Timmy numbers and checking to see if our string was contained in them.

Xanderhall

Posted 2016-11-16T16:41:07.030

Reputation: 1 236

1

Perl 6, 43 34 bytes

Thanks to Jo King for -9 bytes.

{!/0/==set comb $_- S:g/..?/1/²:}

Port of Gabriel Benamy's Perl solution.

Try it online!

bb94

Posted 2016-11-16T16:41:07.030

Reputation: 1 831

0

Cjam, 35 bytes

Probably very suboptimal... I'm a little out of practice!

q__W%=\_,_2%@@2/)<2ew{:-}%e`,1=]:e&

Try it online!

A Simmons

Posted 2016-11-16T16:41:07.030

Reputation: 4 005

0

Python 2, 50 82 81 80 bytes

def f(a):b=len(a)/2+1;print(1,0)[a[:b-1]!=a[b:][::-1]or a[:b]not in'123456789']

Simple approach. Just splits the string in half (missing out the middle character or one after the middle character if it is of even length), reverses the second half then compares the two and compares the first half with a string of 1 to 9.

Edit

Reposted after constructive feedback from fellow golfers and realising and correcting my mistakes.

-1 for losing a (waste of) space

-1 for reading the question again and realising that we don't need to take 0 into account. Really must stop golfing after a long day at work.

ElPedro

Posted 2016-11-16T16:41:07.030

Reputation: 5 301

1This doesn't check if numbers are strictly increasing by one. For example, 13531, and 6543456 both incorrectly return True. – James – 2016-11-16T20:03:12.993

1Also, the strings '0' and '1' are both truthy. – Dennis – 2016-11-16T20:03:42.900

Absolutely right. It's been a long day. Will delete as invalid. – ElPedro – 2016-11-16T20:07:59.643

4Thanks for the comments and not just downvoting. – ElPedro – 2016-11-16T20:09:46.687

0

R, 100 bytes

l=length(x<-el(strsplit(scan(,""),"")));all(x==rev(x))&all(diff(as.numeric(x[1:((l+1)/2)]))==1)&l%%2

Unfortunately, the last Giza number (12345678987654321) is too large to be represented using R's 32-bit integers. Consequently we need to treat input as a string which makes this program slightly longer and we can't effectively rely on calculations.

  1. Read input as string and split into character vector: x<-el(strsplit(scan(,""),""))
  2. Calculate length: l=length(x)
  3. Check if x is equal to itself revered: all(x==rev(x))
  4. and if the difference between the numbers 1...middle are all equal to one: &all(diff(as.numeric(x[1:((l+1)/2)]))==1)
  5. and if number of characters is odd: &l%%2

Billywob

Posted 2016-11-16T16:41:07.030

Reputation: 3 363

0

Haskell, 61 bytes

g[a,b]=0>1
g(a:b:c)=a==last c&&b==succ a&&g(b:init c)
g _=1>0

Angs

Posted 2016-11-16T16:41:07.030

Reputation: 4 825

0

VBA, 175 bytes

Function e(s) As Boolean
Dim f As Long
For i=1 To Int(Len(s)/2)+1
x=Mid(s,i,1)
If f<>0 And ((f+1)<>x) Or (x<>Mid(s,Len(s)-i+1,1)) Then Exit Function
f=x
Next
e=1
End Function

user3819867

Posted 2016-11-16T16:41:07.030

Reputation: 439

You do not need to declare the types of your variables, meaning that you can drop the as boolean, and dim f as long, and further reduce this solution down to Sub e(s):For i=1To Int(Len(s)/2)+1:x=Mid(s,i,1):If f<>0 And ((f+1)<>x)Or(x<>Mid(s,Len(s)-i+1,1)) Then d=1:Exit For:f=x:Next:Debug.?0 ^ d:End Sub – Taylor Scott – 2017-06-05T21:09:13.663