17
\$\begingroup\$

As it turns out, Python allows for 1j for to be compressed to 1jfor. However, jfor sounds like xnor. Since all similar-phonic phrases have something in common, there must be some property shared between jfor and xnor.

If we look at the ASCII representation of the first two characters of jfor in binary, we see:

j:   1101010
f:   1100110
j&f: 1100010

Notice that the bitwise AND of j and f has a streak of 1s at the beginning, then some 0s, then a single 1.

Definition: A pair of numbers meets the JFor property iff their bitwise AND in binary meets the following regex (excluding leading 0s): /1+0+1+0*/ (1 or more 1s, followed by 1 or more 0s, followed by 1 or more 1s, followed by 0 or more 0s)

Do the ASCII codes for x and n meet the JFor property?

x:   1111000
n:   1101110
x&n: 1101000

Yes! So my hunch was correct; jfor and xnor sound similar, and they share a property (This means, of course, that odor must have that property too).

Task

Given a pair of numbers, determine if they meet the JFor property.

The two numbers may not be distinct, but they will both be integers from 0 to 255 respectively.

Output may follow your language's conventions for Truthy and Falsey, or you may choose any two consistent, distinct values to represent truthy and falsey respectively.

Your program/function may take input in any reasonable format to represent an ordered pair of integers/bytes.

Test cases

# Truthy:
106 102
110 120
42 26
17 29
228 159
255 253

# Falsey:
85 170
228 67
17 38
255 255
38 120
21 21

(Bounty: 50 rep to the shortest answer on July 24 if it somehow uses a XOR or XNOR operation; please mention if your submission qualifies)

\$\endgroup\$
6
  • 2
    \$\begingroup\$ 102&70=70 -> 1000110 - isn't that truthy? \$\endgroup\$ Jul 17, 2020 at 18:42
  • 2
    \$\begingroup\$ Also, I suggest a falsey case with more runs than required like 21 21. \$\endgroup\$ Jul 17, 2020 at 18:56
  • 1
    \$\begingroup\$ @JonathanAllan Fixed; changed the 102 70 test case to 21 21 \$\endgroup\$ Jul 17, 2020 at 19:12
  • \$\begingroup\$ May we output one consistent value for truthy and any other value for falsey, or vice-versa? \$\endgroup\$
    – Shaggy
    Jul 17, 2020 at 20:10
  • \$\begingroup\$ @Shaggy "or you may choose any two consistent, distinct values to represent truthy and falsey respectively." \$\endgroup\$ Jul 17, 2020 at 20:10

18 Answers 18

22
\$\begingroup\$

Python, 34 bytes

lambda a,b:bin(a&b).count('01')==1

Try it online!

Although this doesn't use xor, I'm xnor.

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

Python 2,  42  41 bytes

Uses XOR, ^

-1 thanks to Neil (double rather than halve).

lambda a,b:bin(a&b^(a&b)*2).count('1')==4

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ lambda a,b:bin(a&b^a*2&b*2).count('1')==4? \$\endgroup\$
    – Neil
    Jul 17, 2020 at 20:14
  • \$\begingroup\$ 39 bytes in Python 3.10: lambda a,b:(a&b^(a&b)*2).bit_count()==4. \$\endgroup\$
    – ovs
    Jul 18, 2020 at 9:46
4
\$\begingroup\$

perl -Mfeature=bitwise -alp, 41 40 bytes

$_=2==(()=sprintf("%b",$_&$F[1])=~/1+/g)

Try it online!

How does it work?

The program reads lines from STDIN, expecting two numbers on each line. 1 is printed for pairs of numbers with the jfor property, an empty line for pairs without the jfor property.

The -p switch makes that the program loops over each line of the input, making the line available in $_. And the end, it will print whatever is in $_. The -l switch removes the trailing newline. The -a switch makes that the input is split on white space, with the components placed in @F. In particular, the second number will be in $F[1].

$_ & $F [1]

Due to the -Mfeature=bitwise switch, this makes & treat its operands as numbers, and performs a bitwise and on them. This makes that while $_ contains both numbers, only the first number is considered, as that is what Perl does with a string which is used as a number: if the beginning looks like a number, this is taken. (atoi, atof, yada, yada, yada). So, we're doing a bitwise and of the two numbers.

sprintf ("%b", ...)

This returns the result in a binary representation.

() = ... =~ /1+/g

Find all the sequences of consecutive 1s. This is assigned to a list (of 0 variables). We're throwing away the results, but assignment itself does have a return value; for a list assignment, the result is the number of elements on the RHS.

$_ = 2 == (...)

Compares the result (of the list assignment above) to 2. If equal, set $_ to 1, else to the empty string.

Edit: Saved a byte by looking at sequences of 1, instead of a full pattern.

\$\endgroup\$
4
\$\begingroup\$

C (gcc), 53 bytes

f(a,b){for(a&=b,b=0;a;a=~a)for(b++;~a&1;a/=2);a=b^4;}

Try it online!

Returns 0 if the two numbers do have the JFor property, and truthy otherwise.

\$\endgroup\$
4
\$\begingroup\$

Japt -!, 11 9 bytes

r& ¤ÔèA É

Try it

r& ¤ÔèA É     :Implicit input of integer array
r             :Reduce by
 &            :  Bitwise AND
   ¤          :Convert to binary string
    Ô         :Reverse
     è        :Count the occurrences of
      A       :  10, which gets coerced to a string
        É     :Subtract 1
              :Implicit output of Boolean negation
\$\endgroup\$
3
\$\begingroup\$

Pip, 11 bytes

1=01NTBaBAb

Try it online! (Verify all test cases)

The main trick is borrowed from xnor's Python answer: the property is satisfied if the binary representation of the bitwise AND contains the sequence 01 exactly once.

1=01NTBaBAb
             a and b are command-line args (implicit)
  01         01 (an integer literal, but treated as a string unless used in a numeric operation)
    N        Count occurrences in:
       aBAb   Bitwise AND of a and b
     TB       Converted to binary
1=           Test whether the number of occurrences equals 1 (0 if not, 1 if so)
             Autoprint (implicit)
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Pip ? Ha-ha pip is python package management system ;) \$\endgroup\$ Jul 18, 2020 at 17:56
  • \$\begingroup\$ Yeah... people have brought that up before. :P I guess I wasn't enough of a Pythonista to know about pip back when I thought it would be funny to name my golf language "Pip Isn't Python". \$\endgroup\$
    – DLosc
    Jul 18, 2020 at 18:11
2
\$\begingroup\$

Python 3, 137 bytes

def f(x,y):
	b=format;z='08b';x=b(x,z);y=b(y,z);a=""
	for i in range(8):a+=str(int(x[i])and int(y[i]))
	return int(a[7])+a.count("10")==2

Try it online!

\$\endgroup\$
1
  • \$\begingroup\$ a=x&y;return(a&1)+bin(a&255).count("10")==2. a simplifies down to a bitwise and \$\endgroup\$
    – rrao
    Jul 19, 2020 at 7:46
2
\$\begingroup\$

Jelly,  9  8 bytes

&BḄƝċ1=1

A dyadic Link accepting which yields 1 if jfor or 0 if not.

Try it online! Or see the test-suite.


8 bytes using XOR

-2 thanks to Neil (double rather than halve).

&Ḥ^$BS⁼4

Try it online!.

\$\endgroup\$
2
  • \$\begingroup\$ &Ḥ^$BS=4? \$\endgroup\$
    – Neil
    Jul 17, 2020 at 20:23
  • \$\begingroup\$ @Neil Oh, yeah. \$\endgroup\$ Jul 17, 2020 at 20:28
2
\$\begingroup\$

APL (Dyalog Extended), 9 bytes

2=≢⊆⍨∧/⊤⎕

Try it online!

How it works

2=≢⊆⍨∧/⊤⎕  ⍝ Full program; input = a vector of two numbers
       ⊤⎕  ⍝ Binary representation of two numbers
     ∧/    ⍝ Bitwise AND
   ⊆⍨      ⍝ Extract chunks of ones
2=≢        ⍝ Test if there are exactly two chunks
\$\endgroup\$
2
\$\begingroup\$

R, 37 34 33 bytes

-3 bytes thanks to Dominic van Essen

function(x,y)sum(rle(x&y)$v>0)==2

Try it online!

Takes input as raw bytes, as given by intToBits. In R, this gives a length 32 vector with the least significant bit first, therefore padded with many zeros. Then compute the run lengths, i.e. sequences of consecutive identical elements. The JFor property is verified if there are exactly two runs of 1s.


A (dumb) solution with XOR is:

R, 39 bytes

function(x,y)xor(sum(rle(x&y)$v>0)-2,1)

Try it online!

\$\endgroup\$
2
  • 1
    \$\begingroup\$ Or using the $values component of rle for 34 bytes \$\endgroup\$ Jul 18, 2020 at 20:39
  • \$\begingroup\$ @DominicvanEssen Nice, thanks! I was convinced that you couldn't compare raws with integers, but I was wrong! \$\endgroup\$ Jul 18, 2020 at 20:43
1
\$\begingroup\$

Charcoal, 23 19 bytes

≔&NNθ⁼⁴Σ⍘⁻|⊗θθ&⊗θθ²

Try it online! Link is to verbose version of code. Outputs a Charcoal boolean i.e. - for JFor, nothing if not. Edit: Switched to my version of @JonathanAllan's answer to save 4 bytes. Explanation:

≔&NNθ

Input the two numbers and take their bitwise AND.

⁼⁴Σ⍘⁻|⊗θθ&⊗θθ²

Take the bitwise XOR of twice the number with itself (Charcoal has no XOR operator, so I have to do this longhand) and check that the result (in base 2) has exactly four 1 bits.

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

C# (Visual C# Interactive Compiler), 58 bytes

a=>b=>Regex.Matches(Convert.ToString(a&b,2),"01").Count==1

Try it online!

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

APL+WIN, 24 bytes and uses xnor

Prompts for input as a vector of 2 integers:

4=+/b≠9↑1↓b←∊×/(⊂9⍴2)⊤¨⎕

Try it online! Coutesy of Dyalog Classic

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

Perl 5 +-pl, 35 bytes

$_=unpack(B8,$_&<>)=~/^0*1+0+1+0*$/

Try it online!

Explanation

This accepts characters as input to allow using unpack to get the first 8 chars of the binary representation of the stringwise AND of $_ (which implicitly contains the input line) and <> (which is the following line of input) and checks for the pattern as specified. Prints 1 for JFor pair or the empty string otherwise.


Perl 5 + -pl, 34 bytes

$_=(@a=unpack(B8,$_&<>)=~/1+/g)==2

This uses @Abigail's counting approach, thanks @Dominic van Essen!

Try it online!

\$\endgroup\$
6
  • 2
    \$\begingroup\$ I think that gives the wrong answer for "5" and "?". The ASCII code of "5" is 53 or 0b110101. The ASCII code for "?" is 63, or 0b111111. Bitwise AND gives us 110101, which is not valid. But your code says its valid (It also fails on the 21 21 test example, but I'm too lazy to figure out how to put chr(21) into TIO). \$\endgroup\$
    – Abigail
    Jul 17, 2020 at 22:15
  • \$\begingroup\$ @Abigail Thank you. As I was going to sleep last night I realised that a 010101 pattern would give a false positive too. I've amended the regex for +6 (!) I'll try and look at this later though... But I suspect using your approach with the unpack mechanism would be the best approach... \$\endgroup\$ Jul 18, 2020 at 6:19
  • \$\begingroup\$ Is there a situation where the g at the end does something? \$\endgroup\$ Jul 18, 2020 at 9:05
  • \$\begingroup\$ @DominicvanEssen In this case there wasn't, so thanks! But in general this returns a list of all the matches and when a list is converted to scalar it returns the number of elements (like in Abigail's answer). You can also use it to easily return the first match in something like ($_)=/match/g. \$\endgroup\$ Jul 18, 2020 at 9:42
  • 1
    \$\begingroup\$ Got it. So I guess that $_=(@a=unpack(B8,$_&<>)=~/1+/g)==2 would be an approach that'd exploit //g to count elements for less bytes? \$\endgroup\$ Jul 18, 2020 at 12:55
1
\$\begingroup\$

Io, 60 bytes

-1 byte thanks to @DLosc.

method(x,y,(x&y)asBinary strip("0")occurancesOfSeq("01")==1)

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ @DLosc I'm impressed! Have you programmed in Io before? \$\endgroup\$
    – user92069
    Jul 19, 2020 at 1:17
  • \$\begingroup\$ Haha, thanks! I haven't, but there are similar functions named strip/lstrip/rstrip in other languages, like Python, so I've seen this kind of one-byte savings before. Then it was just a matter of looking up Io's docs and seeing that it did indeed have strip. \$\endgroup\$
    – DLosc
    Jul 19, 2020 at 1:30
1
\$\begingroup\$

JavaScript (V8), 44 bytes

(a,b)=>(a&b).toString(2).match(/^1+0+1+0*$/)

Try it online!

Takes input as two numbers, returns a binary string if they meet the JFor property, otherwise null

(a,b)=>(~(a^b)&(a|b)).toString(2).match(/^1+0+1+0*$/)

Try it online!

The same function, but instead uses an XOR to get the binary string.

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

05AB1E, 8 7 bytes (without XOR/XNOR bonus)

&b0«ÔCн

Outputs 1 for truthy and 0/2/4 for falsey (only 1 is truthy in 05AB1E, so this is allowed according to rule "Output may follow your language's conventions for Truthy and Falsey").

Try it online or verify all test cases.

8 bytes with XOR bonus:

&x^2вO4Q

Port of @JonathanAllan's Python 2 answer.

Try it online or verify all test cases.

Explanation:

&        # Bitwise-AND the two (implicit) input-integer together
 b       # Convert it to a binary-string
  0«     # Append a trailing 0 at the end
    Ô    # Connected uniquify it
     C   # Convert it from binary back to an integer
         # (which will result in 0/2/10/42; of which only 10 is a truthy test result)
      н  # Pop and leave just the first digit (0/2/1/4, of which only 1 is 05AB1E truthy)
         # (after which the result is output implicitly)

&        # Bitwise-AND the two (implicit) input-integers together
 x       # Double it (without popping)
  ^      # Bitwise-XOR (a&b) with 2*(a&b)
   2в    # Convert this to a binary-list
     O   # Sum that list to get the amount of set bits
      4Q # And check if it's equal to 4
         # (after which the result is output implicitly)

The last four bytes has a few alternatives, like 5%3@ or ₆ÍÃĀ.

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

Scala, 46 45 bytes

_.&(_).toBinaryString matches "1+0+1+0*"

Try it online

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