| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | Python | 241023T112529Z | 138 Aspe |
| nan | Rust | 241026T092412Z | 138 Aspe |
| 093 | C GCC | 241110T170718Z | matteo_c |
| 102 | AWK | 241025T213334Z | xrs |
| 017 | Jelly | 241027T191109Z | Unrelate |
| 027 | APL Dyalog Unicode | 241023T094958Z | Ven |
| 036 | x8664 machine code | 241026T191340Z | m90 |
| 088 | Python 2 | 241024T003518Z | Lucenapo |
| 022 | 05AB1E | 241024T141446Z | Kevin Cr |
| 075 | Python | 241025T044945Z | Albert.L |
| 033 | Charcoal | 241023T212312Z | Neil |
| 020 | Vyxal | 241023T211325Z | emanresu |
| 021 | Jelly | 241023T184442Z | Jonathan |
| 079 | Perl 5 n | 241023T175351Z | Xcali |
| 060 | JavaScript ES10 | 241023T092926Z | Arnauld |
| 043 | Retina | 241023T091329Z | Neil |
| 043 | Uiua | 241023T103638Z | mousetai |
Python, 398 183 168 128 126 124 bytes
Saved 230 bytes thanks to @Malo
Saved 40 bytes thanks to @Dingus
Saved (2+2=4) bytes thanks to @ceilingcat
Golfed version. Attempt This Online!
def p(b):
a=[];b=[0,0]+b+[0]
for i,v in enumerate(b[2:-1]):
n=b[i+3];p=b[i+1]
if[~p^n,(p|n)//2,i][v]&1:a+=i,
return a
Ungolfed version. Attempt This Online!
def process_array(input_array):
# Use list comprehension with conditional filtering (similar to flatMap)
result = []
for current_index, current_value in enumerate(input_array):
# Get the next value in the array (None if beyond array bounds)
next_value = input_array[current_index + 1] if current_index + 1 < len(input_array) else None
# Store the previous value for the next iteration
previous_value = 0 if current_index == 0 else input_array[current_index - 1]
# Determine which operation to perform based on current value
if current_value == 0:
# NOT of previous value XOR with next value
# Using bitwise operators and handling None case
next_val = 0 if next_value is None else next_value
computed_result = (~previous_value ^ next_val)
elif current_value == 1:
# (previous value OR next value) divided by 2
next_val = 0 if next_value is None else next_value
computed_result = (previous_value | next_val) // 2
elif current_value == 2:
# Just return the current index
computed_result = current_index
else:
computed_result = 0
# Check if the least significant bit is set (result is odd)
if computed_result & 1:
result.append(current_index)
return result
# Test cases
test_cases = [
{"input": "101", "expected": [1]},
{"input": "201102", "expected": [5]},
{"input": "1012", "expected": [1, 2, 3]},
{"input": "0", "expected": [0]},
{"input": "20101010002", "expected": [3, 5, 8, 9]},
{"input": "111020100102", "expected": [11]},
{"input": "20110010201", "expected": []},
{"input": "01102011100111100111", "expected": []},
{"input": "20111100102011102010011", "expected": []}
]
# Run test cases
for case in test_cases:
# Convert string to array of numbers
input_array = [int(x) for x in case["input"]]
# Process the array
result = process_array(input_array)
# Compare with expected result
is_correct = result == case["expected"]
# Output result and validation
print(f"{result} {'✔️' if is_correct else '❌'}")
Rust, 223 220 208 200 199 194 bytes
Saved 3+12+8+1+5=29 bytes thanks to @ceilingcat
Tips:
- Use
(0..).zip(i)instead ofi.iter().enumerate()to save bytse. - use
_=>x as i32instead of2=>x as i32,_=>0to save bytes.
Golfed version. Attempt This Online!
fn p(i:&[i32])->Vec<usize>{let mut r=vec![];for(x,&v)in(0..).zip(i){let(n,p)=(i.get(x+1).copied().unwrap_or(0),if x<1{0}else{i[x-1]});if match v{0=>!p^n,1=>(p|n)/2,_=>x as i32}&1>0{r.push(x)}}r}
Ungolfed version. Attempt This Online!
#![allow(warnings)]
fn process_array(input_array: &[i32]) -> Vec<usize> {
let mut result = Vec::new();
for (current_index, ¤t_value) in input_array.iter().enumerate() {
// Get the next value in the array (0 if beyond array bounds)
let next_value = input_array.get(current_index + 1).copied().unwrap_or(0);
// Store the previous value for the next iteration
let previous_value = if current_index == 0 { 0 } else { input_array[current_index - 1] };
// Determine which operation to perform based on current value
let computed_result = match current_value {
0 => {
// NOT of previous value XOR with next value
(!previous_value ^ next_value)
},
1 => {
// (previous value OR next value) divided by 2
(previous_value | next_value) / 2
},
2 => {
// Just return the current index
current_index as i32
},
_ => 0
};
// Check if the least significant bit is set (result is odd)
if computed_result & 1 == 1 {
result.push(current_index);
}
}
result
}
fn main() {
// Define test cases as a vector of tuples (input string, expected result)
let test_cases = vec![
("101", vec![1]),
("201102", vec![5]),
("1012", vec![1, 2, 3]),
("0", vec![0]),
("20101010002", vec![3, 5, 8, 9]),
("111020100102", vec![11]),
("20110010201", vec![]),
("01102011100111100111", vec![]),
("20111100102011102010011", vec![])
];
// Run test cases
for (input_str, expected) in test_cases {
// Convert string to vector of numbers
let input_array: Vec<i32> = input_str
.chars()
.map(|c| c.to_digit(10).unwrap() as i32)
.collect();
// Process the array
let result = process_array(&input_array);
// Compare with expected result
let is_correct = result == expected;
// Output result and validation
println!("{:?} {}", result, if is_correct { "✔️" } else { "❌" });
}
}
// Add tests module
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_basic_cases() {
let test_cases = vec![
(vec![1, 0, 1], vec![1]),
(vec![2, 0, 1, 1, 0, 2], vec![5]),
(vec![1, 0, 1, 2], vec![1, 2, 3]),
(vec![0], vec![0])
];
for (input, expected) in test_cases {
assert_eq!(process_array(&input), expected);
}
}
#[test]
fn test_empty_result_cases() {
let test_cases = vec![
"20110010201",
"01102011100111100111",
"20111100102011102010011"
];
for input_str in test_cases {
let input: Vec<i32> = input_str
.chars()
.map(|c| c.to_digit(10).unwrap() as i32)
.collect();
assert_eq!(process_array(&input), Vec::<usize>::new());
}
}
}
C (GCC), 98 93 bytes
- -5 bytes thanks to @ceilingcat
f(char*x){for(int i=0,p=8;*x;p=*x++,i++)(*x&1?(x[1]|p)/2:*x&2?i:x[1]-~p)%2&&printf("%d ",i);}
AWK, 123 117 115 102 bytes
{$0=0$0;for(i=1;i++<NF;)printf(!$i&&0~($(i-1)+$(i+1))%2||1~$i&&(2~$(i-1)||2~$(i+1))||2~$i&&i%2)?i-2:x}
BEGIN{FS=X}{$0=0$0;for(i=2;i<=NF;i++)printf(!$i&&0~($(i-1)+$(i+1))%2||1~$i&&(2~$(i-1)||2~$(i+1))||2~$i&&i%2)?i-2:x}
{for(i=2;i<=split(0$0,a,X);i++)printf(!a[i]&&0~(a[i-1]+a[i+1])%2||1~a[i]&&(2~a[i-1]||2~a[i+1])||2~a[i]&&i%2)?i-2FS:x}
{for(i=2;i<=split(0$0,a,X);i++)printf(!a[i]&&0~(a[i-1]+a[i+1])%2||1~a[i]&&(2~a[i-1]||2~a[i+1])||2~a[i]&&0~(i-1)%2)?i-2FS:x}
Thank you, emanresu A!
Jelly, 19 17 bytes
ŻṖ»Ịż+ʋḊj"J⁸ị"ḂCT
Program or function taking a list of [0,1,2] blocks and outputting a list of 1-indices. (The test harness converts to 0-indices for convenience.)
Ṗ With the input without its last element
Ż and with a zero prepended
ʋ on the left
Ḋ and the input without its first element on the right,
ż pair corresponding
»Ị maxima-not-being-2
+ and sums.
» + Ḋ (Both give the last element off the end unchanged.)
j"J Insert each pair's 1-index between its elements.
⁸ị" Modular 1-index each input element into its triple:
ż+ j" ⁸ị" 0 maps to the last element, the sum;
»Ịż j" ⁸ị" 1 maps to the first element, the lack of 2;
ż j"J⁸ị" 2 maps to the second/middle element, the 1-index.
T Return the 1-indices of
ḂC even results.
Since Jelly natively uses 1-indexing, the legal positions for a 2 are actually odd indices, so they can be checked uniformly with the sums for 0, as well as the Boolean result of each 1's neighborhood containing a 2.
APL (Dyalog Unicode), 47 43 27 bytesSBCS
⍸⊢∘(⊃2∘⌷↓2|+/,⌈/)⌺3<⊢≤2∨⍳∘⍴
Creates a 3-cases stencil around each elements (those get padded with zeroes). Index into an array computing whether the sum of the 3 is odd (0 being the identity element here) for 0, and for 1 checks if any element is 2 (we know the middle one is 1). No check done for 2 at this stage (index not available at point).
Then a second checks is ORed with the first one, we compute a range of the indices, and keep those for positions of 2.
Once we have a boolean vector, use ⍸ to get the truthy positions.
-4 thanks to @asherbhs. -16 thanks to @att
x86-64 machine code, 36 bytes
31 C0 99 EB 18 34 01 8D 0C 90 32 4E 01 24 02 08 C1 AC 66 0F A3 C1 73 03 89 17 AF FF C2 38 26 75 E4 57 58 C3
Following the standard calling convention for Unix-like systems (from the System V AMD64 ABI), this takes
- in RDI, an address at which to write the output, as an array of 32-bit integers,
- in RSI, the address of the input, as a null-terminated byte string
and returns in RAX the address of the end of the output.
In assembly:
f: xor eax, eax; cdq # Initialise EAX and EDX to 0.
# EAX will hold the previous material, EDX the current index.
jmp c # Jump to the loop test, to handle length-0 input correctly.
r: xor al, 1 # Invert the low bit of EAX. (AL is its low byte.)
lea ecx, [rdx*4+rax] # Set ECX to this value.
# (RDX and RAX are the 64-bit versions of EDX and EAX.)
# The goal is to construct a value in ECX such that
# its nth bit is 1 iff material n is unstable here.
# Multiplying the index by 4 puts its low bit at position 2.
xor cl, [rsi+1] # Exclusive-or the next material into that value.
# Now, bit 0 is the XOR of both low bits and 1, which is correct.
# Bit 1 is the XOR of both materials' bit 1 (which is 1 only for 2),
# which is close, but it should be the inclusive or.
and al, 2 # Mask the previous material to leave only bit 1.
or cl, al # OR in that value, fixing the case of both having bit 1.
lodsb # Load a byte from the string into AL, advancing the pointer.
bt cx, ax # Set CF to the bit in CX indexed by its low 4 bits.
# (CX is the 16-bit version of ECX, so that only 4 bits of EAX are used;
# the next bit is a 1, as ASCII digits begin at 48=0x30.)
jnc s # Jump if CF=0.
mov [rdi], edx # Put the index into the output array.
scasd # Advance the output pointer with an unused comparison.
s: inc edx # Add 1 to the index.
c: cmp [rsi], ah # Compare the next input byte with AH,
# which is the second-lowest byte of EAX, which is 0.
jne r # Jump back, to repeat, if they are not equal.
push rdi; pop rax # Put the final output pointer into RAX for returning.
ret # Return.
Python 2, 104 88 bytes
b=input()+[4]
for i,j in enumerate(b):l=b[i-(i>0):i+2];print`i`*[~sum(l)&1,2in l,i&1][j]
The program terminates with an error after giving the correct output.
05AB1E, 22 bytes
0.øü3εOÈy2åNÉ)yÅsè}ƶ0K
Input as a list of digits; output as a list of 1-based indices.
Try it online or verify all test cases.
Or alternatively:
õªćsv©y)DOÈs2åNÉ)®è–®y
Input can be a string or a list of digits; prints the invalid 0-based indices on separated newlines.
Try it online or verify all test cases.
Explanation:
0.ø # Surround the (implicit) input-list with leading/trailing 0
ü3 # Pop and get all overlapping triplets of this list
ε # Map over each triplet:
O # Sum the triplet
È # Check whether this sum is even
y # Push the triplet again
2å # Pop and check whether it contains a 2
N # Push the 0-based map-index
É # Check whether this index is odd
) # Wrap all three checks into a list
y # Push the triplet again
Ås # Pop and leave its middle
è # Use that to 0-based index into the earlier list
}ƶ # After the map: multiple all checks by their 1-based index
0K # Then remove all 0s
# (after which this is output implicitly as result)
õª # Append an empty string "" to the (implicit) input
# (which also converts it to a list if it wasn't already)
ć # Extract head; push remainder-list and first item separately to
# the stack
s # Swap so the remainder-list is at the top of the stack
v # Pop and loop over each of its values `y`:
© # Store the top of the stack in variable `®` (without popping)
y # Push the current loop-value `y`
) # Wrap all items on the stack into a list
# (2 items in the first iteration; 3 in later iterations)
D # Duplicate this pair or triplet
O # Sum it together
È # Check whether this sum is even
s # Swap so the pair/triplet is at the top again
2å # Pop and check whether it contains a 2
N # Push the 0-based map-index
É # Check whether this index is odd
) # Wrap all three checks into a list
®è # Use `®` to 0-based index into this triplet
– # If it's truthy: print the current loop-index with newline
®y # Push values `®` and `y` for the next iteration
# (if the input-list is valid and no indices were printed at the
# end of the loop, it'll implicitly print the first pushed value
# with trailing newline instead, which is the empty string "")
Python, 75 bytes
-2 thanks to @Jonathan Allan.
lambda l:[j for j,c in enumerate(l)if[~sum(L:=[0,*l][j:j+3]),2in L,j][c]%2]
Python, 77 bytes
lambda l:[j for j,c in enumerate(l)if[~sum(L:=[0,*l][j:j+4:2]),2in L,j][c]%2]
Charcoal, 33 bytes
I⌕AEEθ✂⪫00θκ⁺³κ¹&¹§⟦⊕Σι⁼2⌈ικ⟧§θκ¹
Try it online! Link is to verbose version of code. Explanation: Port of @Arnauld's JavaScript answer.
θ Input string
E Map over characters
00 Literal string `00`
⪫ Joined with
θ Input string
✂ ¹ Sliced from
κ Current index to
κ Current index
⁺ Plus
³ Literal integer `3`
E Map over windows
ι Current window
Σ Sum of digits
⊕ Incremented
ι Current window
⌈ Maximum
⁼ Equals
2 Literal string `2`
κ Current index
⟦ ⟧ Make into list
§ Indexed by
θ Input string
§ Indexed by
κ Current index
& Bitwise And
¹ Literal integer `1`
⌕A Find indices of
¹ Literal integer `1`
I Cast to string
Implicitly print
Vyxal, 20 bytes
0pǏ3lƛ∑₂n2c¥&¬W;¨£iT
0pǏ # Prepend and append a 0
3lƛ ; # Over the subarrays of length 3...
W # Construct a list of
∑₂ # 0 -> Sum even
n2c # 1 -> Contains a 2
¥&¬ # 2 -> Whether the current index is even
¨£i # Index the original values into each list
T # And get the truthy indices of this.
Jelly, 21 bytes
2e;SḂj0Ḋƭ
Ø0jÇ3Ƥ⁸ịƑ"T
A full program that accepts the list of blocks (integers from \$\{0,1,2\}\$) and prints the list of 1-indexed indices of erroneous blocks.
Or see the test-suite. (This calls the code twice for each input just to ensure that the ƭ is in the right state after an odd-length input (hence the "full program" qualification above))
How?
2e;SḂj0Ḋƭ - Helper link: three-slice of blocks, T
2e - does two exist in {T}?
S - sum {T}
; - concatenate -> [2 in T?, sum T]
Ḃ - mod two -> [2 in T? % 2, sum T % 2] (Note: 2 in T? % 2 = 2 in T)
ƭ - on successive calls alternate between:
0 - zero
Ḋ - dequeue {T}
j - join -> [2 in T?, 0 / 2nd element, ...junk..., Sum T % 2]
^ ^ ^
(1-case 2-case 0-case)
Ø0jÇ3Ƥ⁸ịƑ"T - Main Link: list of {0,1,2}, Blocks
Ø0 - [0,0]
j - join with {Blocks} -> 0-padded-blocks
3Ƥ - for each three-slice, from left to right:
Ç - call the helper link -> LookupArray
⁸ - chain's left argument -> Blocks
" - zip with - f(Block, respective LookupArray):
Ƒ - is {Block} invariant under?:
ị - {Block} index into {LookupArray} (1-indexed & modular)
T - truthy indices
Perl 5 -n, 79 bytes
($&-2||pos()%2)&&say pos while /2\K1|1(?=2)|([02]|^\K)0(?=[20]|$)|1\K0(?=1)|2/g
Output is 1-indexed
JavaScript (ES10), 60 bytes
Expects an array of digits.
a=>a.flatMap(p=(v,i)=>[~p^(q=a[i+1]),(p|q)/2,i][p=v]&1?i:[])
Commented
a => // a[] = input array
a.flatMap(p = // initialize p to a zero'ish value
(v, i) => // for each value v at index i:
[ // lookup array:
~p ^ // 0: (NOT predecessor) XOR
(q = a[i + 1]), // successor
(p | q) / 2, // 1: (predecessor OR successor) / 2
i // 2: just use i
][p = v] // get the result at index v and copy v to p
& 1 // test the LSB
? // if it's set:
i // return the position
: // else:
[] // discard this entry
) // end of flatMap()
Retina, 55 48 43 bytes
^|$
0
Iv`101|[02]0[02]|21|.12|(?<!^(..)*).2
Try it online! Outputs unstable positions on separate lines but link is to test suite that joins on commas for convenience. Explanation: The skyscraper is wrapped in 0s for convenience, then I command automatically lists the positions of the matches, while the v modifier allows the matches to overlap, thus avoiding forward lookahead, so it just remains to match the unstable positions, starting at the now previous character, which is at the desired position.