Validate 2Col syntax!

11

2

As a couple of people may have noticed lately, I've largely abandoned development of Braingolf because it's boring and uninspired, and moved on to 2Col which is a little more interesting, and not designed to be a golfing language.

The defining feature of 2Col is that every line of code must be exactly 2 characters long, excluding the newline. This means that the length of a 2Col program can always be calculated as 3n-1 where n is the number of lines in the program.

So here's my challenge: Given 2Col code as a string, output truthy if it is valid 2Col code (Every line is exactly 2 characters and it conforms with the 3n-1 formula), and falsey otherwise.

Input

Input should be taken as a single string, or an array of characters.

Output

A truthy value if the input string is valid layout, and a falsey value otherwise.

Your code should be consistent in which truthy/falsey values it uses

Testcases

======
F!
$^
----
truthy
======


======
*8
+1
Sq
----
truthy
======


======
nop
xt
----
falsey
======


======
+1
+1
#^

----
falsey
======


======
<empty string>
----
falsey
======


======
ye
----
truthy
======


======
no<space>
----
falsey
======


======
test
----
falsey
======


======
puzzle
----
falsey
======

Scoring

This is so fewest bytes wins!

Skidsdev

Posted 2017-05-25T16:22:19.343

Reputation: 9 656

@Shaggy no, not unless for some reason the language you use considers true falsey and false truthy – Skidsdev – 2017-05-25T18:13:40.730

1@StephenS Will do – Skidsdev – 2017-05-25T18:13:49.003

@Mayube thanks, sorry, I forgot to add "could you" in front of that xD – Stephen – 2017-05-25T18:21:23.103

I suggest you add a test case: puzzle. This will make solutions that do the whole length of the string modulo 3, then negated (which works for all the current test cases) invalid. – Comrade SparklePony – 2017-05-25T19:41:42.613

@ComradeSparklePony will do – Skidsdev – 2017-05-25T21:10:46.210

Do you require the 2 output values to be consistent? – Shaggy – 2017-05-26T07:25:39.510

Just curious, is there a way to define new functions in 2Col? – clismique – 2017-05-26T09:57:45.317

@Qwerp-Derp not yet, I'm planning to add a feature that will allow you to jump to another line, and then another that will allow you to jump back, meaning you could define functions that way – Skidsdev – 2017-05-26T10:00:15.317

Isn't from functools import reduce; unnecessary? And also... semicolons? – Esolanging Fruit – 2017-05-30T07:25:00.637

Answers

6

Brachylog (2), 4 bytes

ṇl₂ᵐ

Try it online!

Full program (because this is a ; Brachylog full programs output false. if there was an assertion failure, true. without one).

Explanation

ṇl₂ᵐ
ṇ     Split input into lines
   ᵐ  For each line:
 l₂     Assert that that line has length 2

Subscripts on l are one of Brachylog's newest features (although still older than the challenge), and this is a good challenge to use them on.

user62131

Posted 2017-05-25T16:22:19.343

Reputation:

Although ṇlᵛ2 and ṇlᵛ² would also work. – Unrelated String – 2019-03-09T08:28:36.707

3

JavaScript (ES6), 24 28 25 24 bytes

Fixed program and shaved of three bytes thanks to @PunPun1000

Shaved off one byte thanks to @Shaggy

s=>/^(..\n)*..$/.test(s)

Returns true if valid and false if not.

f=
s=>/^(..\n)*..$/.test(s)

t=
`22
22
22
22
22`

console.log(f(t));
console.log(f(t.slice(0, -1)));

Stephen

Posted 2017-05-25T16:22:19.343

Reputation: 12 293

Just looking at this I don't think it works for two of the test cases (the truthy one with only 2 characters and no new line, and the falsey one with a trailing newline). However s=>s.match(/^(..\n)*..$/) should correctly match both of those while also being shorter at 25 bytes – PunPun1000 – 2017-05-25T18:46:12.730

@PunPun1000 thank you, you are correct. – Stephen – 2017-05-25T19:15:03.757

Unfortunately this is invalid as the 2 output values aren't consistent. However, you should be able to fix that and save a byte by using test instead of match. – Shaggy – 2017-05-28T23:05:35.200

@Shaggy thanks - the reason I didn't see that when I answered because that was just edited in – Stephen – 2017-05-29T01:05:59.687

I know, that's why I pointed it out ;) You might want to update the note on your return values. – Shaggy – 2017-05-29T09:24:42.217

2

Haskell, 23 52 32 bytes

all((==2).length).lines.(++"\n")

I got my inspiration from some other solutions, clever trick adding that "\n".

Program man

Posted 2017-05-25T16:22:19.343

Reputation: 531

I've fixed it, but RIP my short solution. – Program man – 2017-05-26T13:48:54.530

2

Cubix, 20 bytes

Returns 1 for truthy and nothing for falsey

@1OuABq>;;?w-!$@;U_N

Cubified

    @ 1
    O u
A B q > ; ; ? w
- ! $ @ ; U _ N
    . .
    . .
  • ABq slurp in all the input, reverse it and push the EOI(-1) to the bottom of the stack
  • >;; Step into the loop and remove items from the stack
  • ? Test for EOI(-1).
    • If found 1uO@ push 1 to the stack, u-turn onto integer output and halt
    • Otherwise _ reflect back onto the ? which redirects to the w lane shift
  • N-!$@;U push line feed (10) onto the stack, subtract, test result, skip the halt if false, remove the result and u-turn
  • ;;> remove the line feeds from the stack and redirect into the loop.

Try it online!

MickyT

Posted 2017-05-25T16:22:19.343

Reputation: 11 735

2

Python, 51

lambda s:all(len(l)==2for l in(s+"\n").splitlines())

Test case runner:

tcs = {
    "F!\n$^": 1,
    "*8\n+1\nSq": 1,
    "nop\nxt": 0,
    "+1\n+1\n#^\n": 0,
    "": 0,
    "ye": 1,
    "no ": 0,
    "test": 0,
    "puzzle": 0
}
f = lambda s:all(len(l)==2for l in(s+"\n").splitlines())
for tc, expected in tcs.items():
    assert f(tc) == expected

Łukasz Rogalski

Posted 2017-05-25T16:22:19.343

Reputation: 131

1

JavaScript (ES6), 35 24 bytes

s=>!/^.?$|.../gm.test(s)

Try it

f=
s=>!/^.?$|.../gm.test(s)
oninput=_=>o.innerText=f(i.value)
o.innerText=f(i.value=`F!
$^`)
<textarea id=i></textarea><pre id=o>

Shaggy

Posted 2017-05-25T16:22:19.343

Reputation: 24 623

There's gotta be a shorter way to do this with RegEx! Yup (and mine is probably not optimal) – Stephen – 2017-05-25T16:49:12.070

1

Jelly, 6 bytes

ỴL€=2Ṃ

Try it online!

Explanation:

ỴL€=2Ṃ
Ỵ       Split at newlines
 L€     Length of each...
   =2   ...equals two.
     Ṃ  Minimum.

Comrade SparklePony

Posted 2017-05-25T16:22:19.343

Reputation: 5 784

1

Retina, 10 bytes

^..(¶..)*$

Try it online! Outputs 1 or 0 as appropriate.

Neil

Posted 2017-05-25T16:22:19.343

Reputation: 95 035

1

J-uby, 19 18 bytes

:=~&/^(..\n*)..$/m

:=~& makes an anonymous function that takes x and returns 0 if it matches the regex /^(..\n*)..$/m, or nil otherwise.

Cyoce

Posted 2017-05-25T16:22:19.343

Reputation: 2 690

1

05AB1E, 6 bytes

¶¡D2ùQ

Try it online!

¶¡D2ùQ   Argument s
¶¡       Split s on newlines
  D      Duplicate
   2ù    Keep only elements of length 2
     Q   Compare

kalsowerus

Posted 2017-05-25T16:22:19.343

Reputation: 1 894

0

Japt, 7 6 bytes

·eÈʶ2

Try it online


Explanation

     :Implicit input of string "U"
·    :Split to array on newline
eÈ   :Maps over the array, checking that every item's ...
Ê    :length ...
¶2   :Equals 2
     :Implicit output of result

Shaggy

Posted 2017-05-25T16:22:19.343

Reputation: 24 623

0

Java (OpenJDK 8), 25 bytes

s->s.matches("(..\n)*..")

Try it online!

Checks if the input string has any number of lines followed by a line feed and a final line without one (ensures at least one line)

PunPun1000

Posted 2017-05-25T16:22:19.343

Reputation: 973

0

Bash + GNU utilities, 13

grep -qv ^..$

This sets the shell return value (accessible in $?) to 0 for false and 1 for true. This is actually the opposite sense compared to normal shell convention, so to make that right you'd need to do:

Bash + GNU utilities, 15

! grep -qv ^..$

Digital Trauma

Posted 2017-05-25T16:22:19.343

Reputation: 64 644

0

Ruby, 22 bytes

->s{s=~/^(..\n*)..$/m}

Cyoce

Posted 2017-05-25T16:22:19.343

Reputation: 2 690