Never odd or even

15

2

Did you notice, that this is a palindrome?

Input
Non-negative integer number or string representing it

Output
4 possible outputs, representing two properties of number:

  • is it palindrome
  • tricky #2

Tricky #2 property
If number is not palindrome, this property answers the question "Do the first and the last digits have the same parity?"
If number is palindrome, this property answers the question "Do the first and middle digit have the same parity?". For even lengths, the middle digit is one of the center two digits.

Examples

12345678 -> False False
It is not palindrome, first and last digits have different parity

12345679 -> False True
It is not palindrome, first and last digits have same parity

12344321 -> True False
It is palindrome, the first digit 1 and middle digit 4 have different parity

123454321 -> True True
It is palindrome, the first digit 1 and middle digit 5 have same parity

P.S.
You are up to decide output type and format. It could be any 4 distinct values. Just mention it in your answer.

Dead Possum

Posted 2017-04-04T08:41:23.490

Reputation: 3 256

It's not clear what "this number's half" means. I thought it meant n/2, but the clarification seems to imply it's the first or last half stringwise. – xnor – 2017-04-04T09:17:48.693

@xnor Its stringwise – Dead Possum – 2017-04-04T09:19:53.363

I've edited in what I think is a simpler way to state the rule. – xnor – 2017-04-04T09:23:39.257

@xnor Seems good, thank you! – Dead Possum – 2017-04-04T09:31:13.627

Can we assume non-negative integer input? – Titus – 2017-04-04T14:59:51.053

@Titus Yeah, I guess so. I'll add this to post – Dead Possum – 2017-04-04T15:12:12.803

Answers

6

05AB1E, 15, 14 13 bytes (Thanks to Riley and carusocomputing)

ÐRQi2ä¨}ȹRÈQ

Try online

Returns with brackets if it is a palindrome

Returns with 0 if the parity is different, 1 if it is the same

Ð Add input, such that I have enough input to work with

R Reverse the last element of the stack

Q Look if it is the same (takes the two top elements and performs ==)

i If statement, so only goes through when it is a palindrome

2 Push the number 2

ä Split the input in 2 equal slices

¨ Push the first element of the split (1264621 results in 1264)

} End if

È Check if last element is even

¹ Push the first input again

R Reverse that input

È Check if it is even now

Q Check if those even results are the same and implicitly print

P. Knops

Posted 2017-04-04T08:41:23.490

Reputation: 301

2Will you put some explanation of your code? – Dead Possum – 2017-04-04T09:17:27.787

Will do really soon – P. Knops – 2017-04-04T10:13:57.027

1You could use ¨ instead of . – Riley – 2017-04-04T13:16:27.313

You don't need the ending ,, implicit output. Also instead of you can use bifurcate: Â; savings of 2 bytes for 12: ÐRQi¨}ȹRÈQ – Magic Octopus Urn – 2017-04-06T17:45:15.560

I'd test the bifurcate part, it behaves weirdly in certain scenarios, but that , should push you into the lead ;). – Magic Octopus Urn – 2017-04-06T17:47:54.610

The bifurcate does not work, the ending is indeed a bytesaver. Thanks! – P. Knops – 2017-04-06T18:11:16.303

In your explanation, you need to replace 1 with ¨ I think. Also, technically, ¨ means a[:-1]. – Erik the Outgolfer – 2017-04-14T15:53:45.453

8

PHP, 55 52 bytes

echo$p=strrev($n=$argn)==$n,$n-$n[$p*log($n,100)]&1;

takes input from STDIN; run with -R.

output:

  • 10 for palindrome and same parity
  • 11 for palindrome and different parity
  • 0 for non-palindrome and same parity
  • 1 for non-palindrome and different parity

notes:

  • strlen($n)/2 == log($n,10)/2 == log($n,100)
  • if palindrome, compare middle digit $n[1*log($n,100)]
  • if not, first digit $n[0*log($n,100)]
  • ... to whole number (<- lowest bit <- last digit)

Titus

Posted 2017-04-04T08:41:23.490

Reputation: 13 814

You could save one byte by using <?= instead of echo http://sandbox.onlinephpfunctions.com/code/f2f7a31a4ec489e86f15515a128f8430a9c51beb

– roberto06 – 2017-04-05T09:47:55.017

@roberto06 $argn is only defined with -R, and that doesn´t allow tags. – Titus – 2017-04-05T09:50:44.997

OK, didn't know that, thanks. – roberto06 – 2017-04-05T09:53:47.490

@roberto06 Wait ... $argn is also available with -F. But nm. – Titus – 2017-10-08T10:46:04.540

7

Jelly, 16 14 bytes

DµŒḂṄHC×LĊị+ḢḂ

Try it online!

Outputs two lines:

  • 1 for palindrome, 0 for not
  • 0 for tricky #2, 1 for not

Explanation

DµŒḂṄHC×LĊị+ḢḂ    Main link. Argument: n (number)
D                 Get the digits of n
 µ                Start a new monadic chain
  ŒḂ              Check if the digit array is a palindrome (1 if yes, 0 if no)
    Ṅ             Print the result with a newline
     H            Halve (0.5 if palindrome, 0 if not)
      C           Subtract from 1 (0.5 if palindrome, 1 if not)
       ×          Multiply by...
        L         ...length of array (length/2 if palindrome, length if not)
         Ċ        Round up
          ị       Take item at that index from the digits
           +      Add...
            Ḣ     ...first item of digits
             Ḃ    Result modulo 2

PurkkaKoodari

Posted 2017-04-04T08:41:23.490

Reputation: 16 699

I always ask myself, how many different characters do you have to learn to be able to write programs with this? Do you know all the meaning and all the characters? Can you even type the characters without using ALT key or character table? What does an IDE for this look like? – Daniel W. – 2017-04-05T10:07:54.197

3

@DanFromGermany I don't remember most of the characters yet. Because of that I also haven't got to learning the US International keyboard layout, so I just copy the characters from the wiki. Development happens by trial-and-error in TIO.

– PurkkaKoodari – 2017-04-05T10:44:39.600

6

Python 2, 70 68 66 bytes

lambda n:(n==n[::-1],(ord(n[-1])+ord(n[(n==n[::-1])*len(n)/2]))&1)

Try it online!

ovs

Posted 2017-04-04T08:41:23.490

Reputation: 21 408

5

PowerShell, 114 99 bytes

param($n)((0,(($z=$n[0]%2)-eq$n[-1]%2)),(1,($z-eq$n[$n.length/2]%2)))[($n-eq-join$n[$n.length..0])]

Try it online!

Saved 15 bytes thanks to @Sinusoid.

Inputs as a string. Outputs an array of type (0|1) (True|False), with the 0 indicating "not a palindrome" and the 1 indicating "palindrome", and the True indicating parity matches and False otherwise.

This is done by using a pseudo-ternary and indexing into the appropriate place (a,b)[index]. The index ($n-eq-join$n[$n.length..0]) checks whether the input is a palindrome. If it is not, we take the a portion, which is a 0 coupled with whether the parity of the first digit $n[0] is -equal to the parity of the last digit $n[-1]. Otherwise, we're in the b portion, which is a 1 coupled with whether $z (the parity of the first digit) is -equal to the parity of the middle digit $n[$n.length/2].

Previously, I had "$($n[0])" to get the first digit to cast correctly as an integer, since $n[0] results in a char and the modulo operator % coalesces chars based on the ASCII value, not the literal value, whereas a string does the literal value. However, @Sinusoid helped me to see that 0,1,2,...,9 as literal values all have the same parity as 48,49,50,...,57, so if it uses the ASCII value we still get the same result.

That array is left on the pipeline, and output is implicit.

AdmBorkBork

Posted 2017-04-04T08:41:23.490

Reputation: 41 581

Out of curiosity, why did you have to use double quotes and an extra $ when you did modulus %2 to a number? I tried this myself and it wasn't necessary if I individually did each step, but it is when you put it inside an array? Does powershell treat it as a different variable type? – Sinusoid – 2017-04-06T16:01:41.967

@Sinusoid It's taking input as a string, so when $n[0] indexes, it comes out as a char. The cast from char to int forced by the % operator doesn't go from '1' to 1, but to the ASCII value, so it's 49. The "$( )" does an explicit cast to string instead, which properly converts it to 1. ... Although, now that you mention it, the parity of 0..9 is the same as ASCII 48..57, so I can probably golf that down. Thanks! – AdmBorkBork – 2017-04-06T17:09:10.850

@Sinusoid 15 bytes saved, thanks! – AdmBorkBork – 2017-04-06T17:35:03.773

3

Java 8, 205 197 182 168 134 bytes

n->{int l=n.length(),a=n.charAt(0)%2;return n.equals(new StringBuffer(n).reverse()+"")?a==n.charAt(l/2)%2?4:3:a==n.charAt(l-1)%2?2:1;}

Outputs: 1 for false-false; 2 for false-true; 3 for true-false; 4 for true-true.

Explanation:

Try it here.

n->{                     // Method with String parameter and integer return-type
  int l=n.length(),      //  The length of the input String
      a=n.charAt(0)%2,   //  Mod-2 of the first digit
  return n.equals(new StringBuffer(n).reverse()+"")?
                         //  If the String is a palindrome
    a==n.charAt(l/2)%2?  //   And if the first and middle digits are both even/odd
     4                   //    return 4
    :                    //   Else
     3                   //    Return 3
   :a==n.charAt(l-1)%2 ? //  Else-if the first and last digits are both even/odd
    2                    //   Return 2
   :                     //  Else
    1;                   //   Return 1
}                        // End of method

Kevin Cruijssen

Posted 2017-04-04T08:41:23.490

Reputation: 67 575

3

Perl 6, 48 bytes

{($/=.flip==$_),[==] .ords[0,($/??*/2!!*-1)]X%2}

Try it

results in (True True) (True False) (False True) or (False False)

Expanded:

{                  # bare block lambda with implicit parameter 「$_」

  (
    $/ =           # store in 「$/」
    .flip == $_    # is 「$_」 equal backwards and forwards
  ),


  [==]             # reduce the following using &infix:<==> (are they equal)

    .ords\         # list of ordinals (short way to make 「$_」 indexable)
    [
      0,           # the first digit's ordinal
      (
        $/         # if the first test is True (palindrome)
        ??   * / 2 # get the value in the middle
        !!   * - 1 # else get the last value
      )
    ]
    X[%] 2         # cross those two values with 2 using the modulus operator
}

Brad Gilbert b2gills

Posted 2017-04-04T08:41:23.490

Reputation: 12 713

3

VBA, 117 99 bytes

Saved 18 bytes thanks to Titus

Sub p(s)
b=s
If s=StrReverse(s)Then r=2:b=Left(s,Len(s)/2+.1)
Debug.?r+(Left(s,1)-b And 1);
End Sub

It doesn't expand much once formatted:

Sub p(s)
    b = s
    If s = StrReverse(s) Then r = 2: b = Left(s, Len(s) / 2 + 0.1)
    Debug.Print r + (Left(s, 1) - b And 1);
End Sub

Here are the given test case results:

s = 12345678     p(s) = 1 = False False
s = 12345679     p(s) = 0 = False True
s = 12344321     p(s) = 3 = True False
s = 123454321    p(s) = 2 = True True

Engineer Toast

Posted 2017-04-04T08:41:23.490

Reputation: 5 769

Does VBA have bitwise operators? Try &1 instead of mod 2. You might also get rid of the If/Then with r=r+2-2*(left(s,1)-b &1) or even better If s = StrReverse(s) then r=2 and r=r+1-(left(s,1)-b &1) ... and 2 bytes off with reversing the Tricky#2: r=r+(left(s,1)-b &1); save more with printing it directly: Debug.Print r+(left(s,1)-b &1). Should be 95 bytes then; 98 if &1 does not work. – Titus – 2017-04-04T16:08:52.227

@Titus Thanks! I wasn't familiar with bitwise operations at all, actually. VBA does have bitwise operations but they use And instead of just &. I figured out how to implement your first suggestion but I couldn't figure out how you meant to change the 3rd line with StrReverse.

– Engineer Toast – 2017-04-04T17:25:40.813

Sub p(s);b=s;If s=StrReverse(s)Then r=2:b=Mid(s,Len(s)/2+.1,1);Debug.?r+(Left(s,1)-b&1);End Sub -> 0/2 for palindromes, 1/0 for Tricky#2 – Titus – 2017-04-04T17:30:43.350

Oh and you should be able to replace the Mid() with Left(s,Len(s)/2+1) or so. – Titus – 2017-04-04T17:36:17.340

@Titus Ahh, OK. I kept trying to revise the portion that set b to a new value after the If statement. I need get more familiar with bitwise operations, I think... – Engineer Toast – 2017-04-04T17:36:57.740

Why +.1 and not +1? – Titus – 2017-04-04T17:54:41.813

1

@Titus Because VBA is stupid and doesn't always round up from 0.5. It uses round-to-even logic. If the string is 9 characters long, then Len(s)/2 = 4.5 which VBA will round to 4. If it's 7 characters long, then Len(s)/2 = 3.5 which VBA will also round to 4. Adding 0.1 corrects the lunacy.

– Engineer Toast – 2017-04-04T18:55:47.633

1

Haskell, 89 bytes

(x:r)#y=mod(sum$fromEnum<$>[x,y])2
f x|reverse x/=x=2+x#last x|y<-length x`div`2=x#(x!!y)

Try it online! Usage: f "12345". Returns 0 for True True, 1for True False, 2 for False True and 3 for False False.

The function # converts both digit characters into their ascii character codes and sums them. If both are even or both are odd the sum will be even, otherwise if one is even and the other odd the sum will be odd. Calculating modulo two, # returns 0 for equal parity and 1 otherwise. f checks if the input string x is a palindrome. If not then # is called with x and the last character of x and two is added to the result, otherwise if x is palindromic call # with the middle character of x instead and leave the result as is.

Laikoni

Posted 2017-04-04T08:41:23.490

Reputation: 23 676

1

Kotlin, 142 bytes

fun Char.e()=toInt()%2==0;
val y=x.reversed()==x;val z=x.first();println("${y},${if(y)z.e()==x.get(x.length/2).e();else z.e()==x.last().e()}")

Try it online!

fun Char.e() = toInt() % 2 == 0; //character extension function, returns if character(as int) is even

val y = x.reversed() == x
val z = x.first()

println(
"${y} //returns whether or not input is a palindrome
, //comma separator between the values
${if(y) z.e() == x.get(x.length/2).e() // if it's a palindrome compare first and middle parity
else z.e() == x.last().e()}" //else compare first and last parity
)

luminous_arbour

Posted 2017-04-04T08:41:23.490

Reputation: 41

1

CJam, 32 bytes

q:N_W%=N0=~2%NW=~2%N_,2/=~2%3$?=

Input is a number on top of the stack.

Explanation:

q                                 e# Read input:          | "12345679"
 :N                               e# Store in N:          | "12345679"
   _                              e# Duplicate:           | "12345679" "12345679"
    W%                            e# Reverse:             | "12345679" "97654321"
      =                           e# Check equality:      | 0
       N                          e# Push N:              | 0 "12345679"
        0=~                       e# First digit:         | 0 1
           2%                     e# Modulo 2:            | 0 1
             N                    e# Push N:              | 0 1 "12345679"
              W=~                 e# Get last digit:      | 0 1 9
                 2%               e# Modulo 2:            | 0 1 1
                   N              e# Push N:              | 0 1 1 "12345679"
                    _             e# Duplicate:           | 0 1 1 "12345679" "12345679"
                     ,            e# Length:              | 0 1 1 "12345679" 8
                      2/          e# Divide by 2:         | 0 1 1 "12345679" 4
                        =         e# Get digit (as char): | 0 1 1 '5
                         ~        e# Eval character       | 0 1 1 5
                          2%      e# Modulo 2:            | 0 1 1 1
                            3$    e# Copy stack element:  | 0 1 1 1 0
                              ?   e# Ternary operator:    | 0 1 1
                               =  e# Check equality:      | 0 1

Esolanging Fruit

Posted 2017-04-04T08:41:23.490

Reputation: 13 542

1

REXX, 104 100 bytes

arg a
parse var a b 2''-1 c
e=a=reverse(a)
b=b//2
if e then f=b&centre(a,1)//2
else f=b&c//2
say e f

Returns logical value pair 0 0, 0 1, 1 0 or 1 1.

idrougge

Posted 2017-04-04T08:41:23.490

Reputation: 641

1

R, 115 109 105 bytes

w=strtoi(el(strsplit(scan(,""),"")))
c(p<-all(w==rev(w)),w[1]%%2==switch(p+1,tail(w,1),w[sum(1|w)/2])%%2)

Takes input from stdin. Returns FALSE FALSE for False False, FALSE TRUE for False True, TRUE FALSE for True False, and TRUE TRUE for True True.

rturnbull

Posted 2017-04-04T08:41:23.490

Reputation: 3 689

1

AWK, 97 96 bytes

{n=split($0,a,"")
for(;j<n/2;)s+=a[j+1]!=a[n-j++]
x=(a[1]%2==a[s?n:int(n/2)+1]%2)+(s?0:2)
$0=x}1

Simplest usage is to place the code into file: OddEven then do:

awk -f OddEven <<< "some number here"

Output is essentially the bit-sum of the comparisons in the Question, e.g.

0, Not palindrome and first and last digits have different parity
1, Not palindrome and first and last digits have same parity 
2, Palindrome and the first digit and middle digit have different parity
3, Palindrome and the first digit and middle digit have same parity

I tried removing the () from (s?0:2) but this messes up operator precedence somehow.

Robert Benson

Posted 2017-04-04T08:41:23.490

Reputation: 1 339

Saved a byte by moving the increment on j. This means the for() could be replaced with a while(), but no bytes would be saved in doing so :( – Robert Benson – 2017-04-06T13:22:27.173

1

Ruby, 60 + 1 = 61 bytes

Uses the -n flag.

r=->i{$_[i].to_i%2}
p e=$_.reverse==$_,r[0]==r[e ?~/$//2:-1]

Try it online!

Value Ink

Posted 2017-04-04T08:41:23.490

Reputation: 10 608

1

Groovy, 326 303 bytes

Shrunk Code:

String str="12345678";char pal,par;pal=str==str.reverse()?'P':'N';if(pal=='P'){par=(int)str.charAt(0).toString()%2==str.charAt((int)str.length()-1-(int)((str.length()-1)/2))%2?'S':'N'}else{par = (int)str.charAt(0).toString()%2==str.charAt((int)(str.length()-1)%2)?'S':'N'};print((String)pal+(String)par)

Original Code (with Explanation):

Declare str as String                        String str = "12345678"
Declare pal and par as char                  char pal, par
Check if Palindrome or not                   pal = str==str.reverse()?'P':'N'
If Palindrome...                             if (pal=='P') {
and has same parity (S) and if not (N)       par = (int)str.charAt(0).toString()%2==str.charAt((int)str.length()-1-(int)((str.length()-1)/2))%2?'S':'N'
else if not palindrome...                    } else {
and has same parity (S) and if not (N)       par = (int)str.charAt(0).toString()%2==str.charAt((int)(str.length()-1)%2)?'S':'N'
closing tag for if                           }
Print desired output                         print((String)pal+(String)par)

Original Code (without Explanation):

String str = "12345678"
char pal, par
pal = str==str.reverse()?'P':'N'
if (pal=='P') {
    par = (int)str.charAt(0).toString()%2==str.charAt((int)str.length()-1-(int)((str.length()-1)/2))%2?'S':'N'
} else {
    par = (int)str.charAt(0).toString()%2==str.charAt((int)(str.length()-1)%2)?'S':'N'
}
print((String)pal+(String)par)

Input:

Just change "12345678" to another set of non-negative digits.

Output:

"PS" - Palindrome with Same Parity
"PN" - Palindrome with Diff Parity
"NS" - Non-palindrome with Same Parity
"NN" - Non-palindrome with Diff Parity

Jimwel Anobong

Posted 2017-04-04T08:41:23.490

Reputation: 159