Disconnect 4 bits
Jelly, 18 bytes + 0 penalties = 18
79Ọv2;$ḅ⁹b2+4\b4FẠ
Returns 1
if there are no equal bit strings of length 4 or more in the 8-bit word representation of the ASCII string input, and 0
otherwise.
Try it online! (test suite with some extra cases added)
Using Jelly's codepage there are no length 4 or longer substrings of equal bits:
7 0x37 00110111
9 0x39 00111001
Ọ 0xB5 10110101
v 0x76 01110110
2 0x32 00110010
; 0x3B 00111011
$ 0x24 00100100
ḅ 0xD4 11010100
⁹ 0x89 10001001
b 0x62 01100010
2 0x32 00110010
+ 0x2B 00101011
4 0x34 00110100
\ 0x5C 01011100
b 0x62 01100010
4 0x34 00110100
F 0x46 01000110
Ạ 0xAB 10101011
With equal-bit run lengths of:
221323221211111312322133122121221111213121123132213111122211311332313211313211111112
How?
Tricks to avoid demerits are:
to avoid the "convert from character to ordinal" monad
O
by converting the number79
to a character usingỌ
followed by an "evaluation of Jelly code with input",v
.to avoid direct conversion to binary using
B
(0x42
,1000010
) by the simple two-byte alternativeb2
using the generic dyadic base conversion.to avoid a few normal choices for counting the runs of equal bits - first choice would be "all overlapping slices of given length",
ṡ
(0xF5
or11110101
). A second choice might be to utilise "all sublists",Ẇ
(0xCF
or11001111
).
A workaround I used before the current one was to take the increments (between consecutive elements) withI
(putting zeros and ones on an equal footing), and to look for any occurrence of three zeros in a row. To do that I converted all the zeros to ones by use of the binomial function with2c
i.e. 2Cx - making the-1
s become0
s the1
s become2
s, and the0
s become1
s; that way the code can look for the first occurrence of the sublist[1,1,1]
withw111
.
However a shorter way became apparent - to mimic the action of "all overlapping slices of given length",ṡ
, one can use a 4-wise overlapping reduce with some dyad,<dyad>4\
. If this is performed with addition,+4\
, it counts the1
s, so then any0
or4
being present is the indicator to return a truthy value. The issue here is that the next obvious step would be to take the modulo 4 of that to put the0
and4
entries on an equal footing while leaving the other possible values (1
,2
, and3
) unchanged, but+\%4
has\%
inside, which has bit-value 0101110000100100. In order to avoid that penalty the numbers are all converted to base 4 withb4
(mapping0
to[0]
,1
to[1]
,2
to[2]
,3
to[3]
, and4
to[1,0]
) and the whole list is flattened withF
. Now the last test is simply to check if there are any0
s in the list, achievable directly with the monadẠ
.
79Ọv2;$ḅ⁹b2+4\b4FẠ - Main link: printable ASCII character list
79 - 79
Ọ - character from ordinal : 'O'
v - evaluate as Jelly code : input -> 'O' converts the input to ordinals
$ - last two links as a monad
2 - 2
; - concatenate (why? see the note beneath the code block)
ḅ⁹ - convert from base 256 : gets an integer representing the byte string
b2 - convert to base 2 AKA binary
4\ - 4-wise reduce with
+ - addition (sums all overlapping slices of length 4)
b4 - convert to base 4 (vectorises)
F - flatten into a single list
Ạ - any falsy?
Note: The reason a 2 is concatenated with the ordinal list is to deal with the edge cases where the only run of 4 in the input string is in the leading zeros of the very first character - these characters are: tab; line-feed; and carriage-return. Without this the base 256 conversion effectively strips leading zeros from the (fully concatenated) binary string; with the leading 2 the leading zeros will be there and an extra one and zero before them. Since no printable ASCII has exactly three leading zeros there is no need to discard these extra bits before the rest of the check.
Java 7, 812 726 673 644 634 616 599 588 145 bytes + 10*44 = 585
boolean
b(char[]b){String
g="";for(char
c:b)g+=g.format("%"+(1-1)+"8d",new
Integer(Integer.toString(c,2)));return!g.matches(".*(.)\\1\\1\\1.*");}
I am using newlines instead of spaces to try to minimize penalty...
Try it online!
Binary
01100010011011110110111101101100011001010110000101101110000010100110001000101000011000110110100001100001011100100101101101011101011000100010100101111011010100110111010001110010011010010110111001100111000010100110011100111101001000100010001000111011011001100110111101110010001010000110001101101000011000010111001000001010011000110011101001100010001010010110011100101011001111010110011100101110011001100110111101110010011011010110000101110100001010000010001000100101001000100010101100101000001100010010110100110001001010010010101100100010001110000110010000100010001011000110111001100101011101110000101001001001011011100111010001100101011001110110010101110010001010000100100101101110011101000110010101100111011001010111001000101110011101000110111101010011011101000111001001101001011011100110011100101000011000110010110000110010001010010010100100101001001110110111001001100101011101000111010101110010011011100010000101100111001011100110110101100001011101000110001101101000011001010111001100101000001000100010111000101010001010000010111000101001010111000101110000110001010111000101110000110001010111000101110000110001001011100010101000100010001010010011101101111101
Old bitshifting solution 141 bytes + 10*101 = 1,151
boolean
b(char[]b){
int
o=0,p=0,i;
for(char
c:b){for(i=0;i<8;){if((c&(1<<i++))<1){o=0;p++;}else{p=0;o++;}if(3<o|3<p)return
6<5;}}return
5<6;}
Try it online!
Binary
011000100110111101101111011011000110010101100001011011100000101001100010001010000110001101101000011000010111001001011011010111010110001000101001011110110000101001101001011011100111010000001010011011110011110100110000001011000111000000111101001100000010110001101001001110110000101001100110011011110111001000101000011000110110100001100001011100100000101001100011001110100110001000101001011110110110011001101111011100100010100001101001001111010011000000111011011010010011110000111000001110110010100101111011011010010110011000101000001010000110001100100110001010000011000100111100001111000110100100101011001010110010100100101001001111000011000100101001011110110110111100111101001100000011101101110000001010110010101100111011011111010110010101101100011100110110010101111011011100000011110100110000001110110110111100101011001010110011101101111101011010010110011000101000001100110011110001101111011111000011001100111100011100000010100101110010011001010111010001110101011100100110111000001010001101100011110000110101001110110111110101111101011100100110010101110100011101010111001001101110000010100011010100111100001101100011101101111101
APL (Dyalog Classic), 26 + 1 × 10 = 36 bytes
Notes
Contains one 4-run of 1s. Requires ⎕IO←0
which is default on many systems. Note that this must be run on a Classic interpreter so that strings are one byte per character.
Submission
1≠⊃⌽⌈\∊(×4\¨⍳≢⍬⍬)⍷¨⊂11⎕DR⍞
Try it online!
Binary source
0011000110101100100111001011001010010111010111001011100100101000110101110011010001011100101010001011110010111011101010111010101100101001101110101010100010011011001100010011000110001100010001000101001010001101
Explanation
⍞
Prompt for string input
11 ⎕DR
convert to 1-bit Boolean (1) Data Representation
⊂
enclose so we can apply multiple things to it
(
…) ⍷¨
binary indicators where each of the following sequences begin…
×
sign (no-op on binary data, but included as spacer to split runs)
4 \¨
expand (copy) each to length four
⍳
the integers up to
≢
the tally of
⍬⍬
the list consisting of two empty numeric lists
∊
enlist (flatten)
⌈\
cumulative maximum
⌽
reverse
⊃
pick the first
1 ≠
is one different from? (i.e. NOT)
Walk-through
We will input "48" to the ungolfed un-de-runned version ~ ∨/ ∊ (0 0 0 0)(1 1 1 1) ⍷¨ ⊂ 11 ⎕DR ⍞
:
11 ⎕DR ⍞
converts "48" to 0 0 1 1 0 1 0 0 0 0 1 1 1 0 0 0 (i.e. Dec 52 56, Hex 34 38)
(0 0 0 0)(1 1 1 1) ⍷¨ ⊂
finds beginnings of 0-runs and 1-runs; (0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 0) (0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0)
∨/ ∊
looks if there is any Truth (i.e. any runs); 1
~
negates that; 0