0

I am trying to sift digits from a numeral string and count each occurrence of each different numeral. To my eyes, my syntax looks correct but I am constantly receiving a syntax error on my case statement; "unexpected 'when'". Can someone please tell me what I am doing wrong here?

prime_string = "23571113171923293137414347535961677173798389971011031071091131271311371391"

zeroes = 0
ones = 0
twos = 0

count_array = [zeroes, ones, twos]

def numsort(d)
    case d
    when 0
        zeroes++
    when 1
        ones++
    when 2
        twos++
    else
        puts "err"
    end
end

while prime_string.length > 0 do 
    numsort(prime_string.split.shift)
end

puts count_array
  • It is missing its `end` – Michael Berkowski Aug 05 '21 at 18:08
  • Oh heh, also no `++` in ruby. https://stackoverflow.com/questions/3717519/no-increment-operator-in-ruby Use `zeroes +=1` instead – Michael Berkowski Aug 05 '21 at 18:10
  • We could first convert the string to an array: `prime_string.chars #=> ["2", "3", "5",..., "9", "1"]`. Next invoke [Enumerable#tally](https://ruby-doc.org/core-2.7.0/Enumerable.html#method-i-tally) on the array to create a *counting hash*: `prime_string.chars.tally #=> {"2"=>4, "3"=>14, "5"=>3, "7"=>12, "1"=>22, "9"=>8, "4"=>3, "6"=>2, "8"=>2, "0"=>4}`. Then use [Hash#values_at](https://ruby-doc.org/core-2.7.0/Hash.html#method-i-values_at) to construct the array `count_array`: `prime_string.chars.tally.values_at("0", "1", "2") #=> [4, 22, 4]`. – Cary Swoveland Aug 05 '21 at 20:34
  • We could improve this in two ways. First, before creating the counting hash, select only the elements of interest from the array produced by `prime_string.chars`: `prime_string.chars.select { |c| ["0", "1", "2"].include?(c) } #=> ["2", "1", "1", ..., "1"]`. Secondly, if we replace `chars` with `each_char` we get an *enumerator*, which requires less storage than the (intermediate) array `prime_string.chars`. We then obtain `prime_string.each_char.select { |c| ["0", "1", "2"].include?(c) }.tally.values_at("0", "1", "2") #=> [4, 22, 4]`. – Cary Swoveland Aug 05 '21 at 20:40
  • Note that even though the counting hash contains only keys `"0"`, `"1"` and `"2"`, those keys might be in any order, so we need `values_at` to extract the values of those keys in the correct order. (We cannot use `h.values`, where `h` is the hash.) – Cary Swoveland Aug 05 '21 at 20:42

1 Answers1

0

There is no ++ operator in ruby.

You need to write += 1 instead.

Whilst this would admittedly have caused a somewhat cryptic error message due to the syntax error, a couple of things I'd note are:

  1. Read the error message carefully. It tells you the line number of the error which, in this case, should probably point to the first occurrence of ++?
  2. Use a better IDE/editor setup! Coding in a poor environment is like writing software whilst wearing handcuffs. Your editor should have warned you about invalid syntax here, before even trying to run the code.
Tom Lord
  • 27,404
  • 4
  • 50
  • 77
  • Ahh geez. Thats what I get for switching between languages... Thanks. Im fairly new so I havent spent much time and effort learning how to configure VSC because i don't have a clear idea of my preferences and needs. – Dylan Knorr Aug 05 '21 at 18:15
  • There's also a missing `end` on the case statement -- which, again, tells me: *use a better IDE setup to warn you about syntax errors*. It looks like you're trying to write Python in Ruby :) – Tom Lord Aug 05 '21 at 18:17
  • **Also**, why is your so-called `prime_string` variable actually an `Integer`? Strings must be wrapped in quotation marks, and switching languages is no excuse for that mistake... – Tom Lord Aug 05 '21 at 18:19
  • *Also also*, there's a much easier way to do this in ruby; the core language has a very convenient method: `Enumerable#tally`. You could do something like `prime_string.chars.tally`, or `prime_number.digits.tally`. – Tom Lord Aug 05 '21 at 18:21
  • The missing end and missing quotes are actually from trying to simplify my code for SO though Python3 was my first language. Thanks for the tip on tally as well. Ill give it a shot. – Dylan Knorr Aug 05 '21 at 18:21