12
\$\begingroup\$

Given an infix expression, determine whether all constants are of the same type.

Operators will consist only of these dyadic operators: +-/*

Your program or function should take a valid expression string as input, and output a truthy value if the constants in the expression are of the same time, and a falsey value otherwise.

The expression will consist solely of constants, and may contain any of the following types:

  • String, of the form "String" (Always double quotes, can be empty, no escape characters, may contain any ASCII text)
  • Integer, of the form 14 (Always positive or zero)
  • Float, of the form 7.3f (Always positive or zero, always has a decimal component, eg 14.0f)
  • Byte, of the form 0x42 (0-255, Always 2 hexadecimal characters)
  • Boolean, of the form true (true or false, case insensitive)

The expression will not contain parentheses, as order of operation doesn't affect type when no type coercion is present.

A lone constant with no operators is a valid expression.

An empty expression is not a valid expression.

You may assume that the expression string contains no whitespace outside of string literals.
Note: Alternatively you may assume that there will always be spaces between constants and operators, as seen in the testcases. If you make this assumption, please specify as such in your answer

You do not have to handle invalid expressions such as 1 +.

Scoring

This is , so fewest bytes wins!

Test cases

(Whitespace added for readability)

2 + 3
True

"Hello" / "World"
True

true * false
True

"Hello" + 4
False

"Hello" + "4"
True

3 + 2.4f / 8
False

0xff * 0xff
True

0xff + 2
False

6
True

" " + ""
True

"4 + false" + "word"
True
\$\endgroup\$
3
  • 4
    \$\begingroup\$ Does "case insensitive" for Boolean values mean that we have to support all cases? Or that we can decide which case to use? \$\endgroup\$
    – Arnauld
    Apr 30, 2019 at 16:09
  • \$\begingroup\$ @Arnauld must support all cases \$\endgroup\$
    – Mayube
    Apr 30, 2019 at 16:31
  • \$\begingroup\$ @JonathanAllan my interpretation was that we had to handle any mixture of cases (e.g. truE+fALSe). If not I can save two bytes in my solution. \$\endgroup\$ Apr 30, 2019 at 19:50

10 Answers 10

11
\$\begingroup\$

JavaScript (ES6),  79 77  75 bytes

Saved 2 bytes thanks to @ExpiredData

Expects whitespace around operators. Returns a Boolean value.

s=>![/".*?"/g,/0x../g,/\S+f/g,/\d/,/e/i].filter(e=>s!=(s=s.split(e)+''))[1]

Try it online!

How?

  1. We remove all strings, using /".*?"/g
  2. We remove all bytes, using /0x../g
  3. We remove all floats, using /\S+f/g
  4. We look for a remaining digit with /\d/; if we do find one, there must be at least one integer
  5. We look for a remaining "e" or "E" with /e/i; if we do find one, there must be at least one Boolean value

All removed expressions are actually replaced with a comma, which is harmless.

We filter out the regular expressions causing no change to the input string and test whether less than two of them remain at the end of the process.

\$\endgroup\$
4
  • \$\begingroup\$ true and false are marked as being case insensitive, I think that means you need to make your regex ignore case when searching for these t and s (I could be wrong though). \$\endgroup\$ Apr 30, 2019 at 16:03
  • 1
    \$\begingroup\$ @JonathanAllan I've put a temporary fix and asked the OP. \$\endgroup\$
    – Arnauld
    Apr 30, 2019 at 16:09
  • \$\begingroup\$ 75 bytes \$\endgroup\$ May 1, 2019 at 7:57
  • \$\begingroup\$ @ExpiredData Nice. :) Thanks! \$\endgroup\$
    – Arnauld
    May 1, 2019 at 8:08
3
\$\begingroup\$

Jelly, 30 23 bytes

ṣ”"ŒœḢYŒlḲŒœḢeþ@“.e¶x”E

Try it online!

A monadic link that takes a string as input and returns 1 for true and 0 for false (Jelly’s boolean values). Expects whitespace around operators.

I’ve added a few new test cases to the TIO including one with three operators and one with mixed case for booleans.

Explanation

ṣ”"                     | Split input at double-quotes
   Œœ                   | Split into two lists, one of odd indices and one even. The even indices will have the contents of the quoted bits in the input (if any)
     Ḣ                  | Keep only the odd-indexed items
      Y                 | Join with newlines (so now all quoted strings in input are a single newline)
       Œl               | Convert to lower case (so that booleans are case insensitive)
         Ḳ              | Split at spaces
          ŒœḢ           | As before just take odd indices
             eþ@“.e¶x”  | Check for each section which they contain of .e¶x (respectively floats, booleans, strings and hex; integers will have none of these)
                      E | Check each section is equal (will return true for single section)
\$\endgroup\$
3
\$\begingroup\$

Perl 5 -p, 73 bytes

for$f(qw/".*?" \d+.\d+f 0x.. ....?e \d+/){s/$f//gi&&last}$_=/^[+\/* -]*$/

Try it online!

How?

Attempt to remove strings, floats, hex, boolean, and integers, in that order. Stop as soon as something is removed. After stopping, check to see if the remaining string consists only of operators and whitespace. It if does, the trype check is true; if not, it's false.

First attempt: Perl 5 -MList::Util=all -p, 99 bytes

s/".*?"/!/g;for$f(qw/! \d+ \d+\.\d+f 0x[0-9a-f]{2} (true|false)/){$\||=all{/^$f$/i}/[^+\/* -]+/g}}{

Try it online!

\$\endgroup\$
3
  • \$\begingroup\$ $_=/^[+\/* -]*$/ may be changed by $_=!y#-+/* ##c, and ....?e by .*e \$\endgroup\$ May 2, 2019 at 9:11
  • \$\begingroup\$ otherwise in one regex, 63 bytes \$\endgroup\$ May 2, 2019 at 9:22
  • \$\begingroup\$ 58 bytes assuming there will always be spaces between constants and operators \$\endgroup\$ May 2, 2019 at 9:37
1
\$\begingroup\$

C# (Visual C# Interactive Compiler), 113 111 109 bytes

n=>@""".*?"" 0x.. \S+f \d e|E".Split().Single(x=>n!=(n=System.Text.RegularExpressions.Regex.Replace(n,x,"")))

Port of Arnauld's javascript answer. Is 72 bytes with the flag /u:System.Text.RegularExpressions.Regex.

Try it online!

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

Japt -!, 36 bytes

`".*?" 0x.. %S+f %d e|E`¸è@UÀ(U=rXÃÉ

Try it

\$\endgroup\$
1
  • \$\begingroup\$ 33 bytes? \$\endgroup\$
    – Shaggy
    May 1, 2019 at 22:31
1
\$\begingroup\$

05AB1E, 50 24 bytes

'"¡āÉÏ»lð¡āÉÏε".e
x"Så}Ë

-26 bytes by making a port of @NickKennedy's Jelly answer, so make sure to upvote him!!

Expects input with spaces at the operands.

Try it online or verify all (plus some more) test cases.

Explanation:

'"¡         '# Split the (implicit) input-string by '"'
   āÉÏ       # Only keep all values at 0-based even indices
      »      # Join them by newlines
       l     # Converted to lowercase (for `true`/`false`)
ð¡           # Split by spaces (NOTE: `#` cannot be used here, since inputs without
             # operands wouldn't be wrapped inside a list)
  āÉÏ        # Keep all values at 0-based even indices again
     ε".e
     x"Så}   # Check for each item for each of [".","e","\n","x"] if it's in the item
          Ë  # Check if all inner lists are the same
             # (which is output implicitly as result)
\$\endgroup\$
0
0
\$\begingroup\$

Python 2, 102 bytes

import re
def f(s):
	m=map(eval,re.split('[*+-/]',s))
	return all(map(lambda t:type(t)==type(m[0]),m))

Try it online!

Not entirely sure how to represent some of these types in Python. For example, 0xff and 2 are both treated as integers. And 2.4f isn't a valid type in Python, I think. Capitalized True and False for testing Booleans.

Edit: Grammar

\$\endgroup\$
4
  • 3
    \$\begingroup\$ Will fail the last test case \$\endgroup\$
    – Gymhgy
    Apr 30, 2019 at 16:08
  • \$\begingroup\$ ...and (as it stands) the true * false one. \$\endgroup\$ Apr 30, 2019 at 18:46
  • \$\begingroup\$ It passes for "True * False". I can try to make it work with lower case, but I figured since bools are always capitalized in python it would be sufficient. \$\endgroup\$
    – GotCubes
    Apr 30, 2019 at 19:12
  • 3
    \$\begingroup\$ Currently this does not fulfill the challenge criteria. Namely: It does not handle booleans case insensitively, it errors on floats, and it incorrectly returns true when given an expression consisting of bytes and integers \$\endgroup\$
    – Mayube
    May 1, 2019 at 13:38
0
\$\begingroup\$

Stax, 26 bytes

ïd"┬Z\¡►L!8$lm╗╕╤☻ú≡╝ò6Å>^

Run and debug it

This program expects spaces around the operators. In general, it works by applying a few transformations to the input such that the maximum character for each expression type is distinct.

Unpacked, ungolfed, and commented, it looks like this.

i           suppress automatic evaluation of input
'"/2::'s*   replace quoted strings with 's'
.\d'9R      replace all digits with '9'
.ez|t       replace 'e' with 'z'
j2::        split on spaces, and discard alternating groups (operators)
{|Mm        calculate the maximum character in each remaining group
:u          resulting array contains exactly one distinct value

Run this one

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

Haskell, 140 Bytes

r(a:t)|a=='"'=a:r(tail$snd$span(/=a)t)|elem a"+-*/"=r t|0<1=a:r t
r n=n
f x|z<-[last$'i':(filter(`elem`t)"fex\"")|t<-words$r x]=all(==z!!0)z
\$\endgroup\$
1
  • 2
    \$\begingroup\$ f x=let z=...in ... can be f x|z<-...=.... \$\endgroup\$ Mar 21, 2020 at 15:35
0
\$\begingroup\$

JavaScript: 69 bytes.

a=>{b=a.split(/\+|\-|\*|\//);return typeof eval(b[0])==typeof eval(b[1])}

Remarks

  • eval is a dangerous operation.
  • I used bad JavaScript practices in the process, like implicit globals and auto-semicolons.

Explanation

  • b = ... sets the variable b to the array created by splitting a based on the dyadic operations
  • return ... returns true if the types of the return values of eval match, false otherwise.
\$\endgroup\$
3
  • 2
    \$\begingroup\$ Don't worry about good practices here. In our daily jobs we are not doing things seen here. ☺ Your code could be reduced to a=>typeof eval((b=a.split(/\+|\-|\*|\//))[0])==typeof eval(b[1]), but unfortunately its glitches would stay: 1) Integers, floats and hexadecimal will all result “number” while the requirement asks to find them different. 2) Your solution should also handle expressions with fewer or more than 2 constants. \$\endgroup\$
    – manatwork
    Feb 2, 2021 at 12:21
  • 2
    \$\begingroup\$ On code golf, it would be worrying if you hadn't used bad practices ;) \$\endgroup\$
    – xigoi
    Feb 2, 2021 at 15:29
  • \$\begingroup\$ Does it handle string with symbol +? \$\endgroup\$
    – l4m2
    Jul 7 at 4:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.