5
\$\begingroup\$
  • There's a question with a comment with some code thats far too long.
  • For a site that has counting fetish, this code just seems so wrong.

  • Solve this meta-riddle, and explain it with a rhyme.

  • Winner is the shortest code in a fortnights time.

The challenge:

  1. Open a file as input.
  2. Count and output the number of digits (0,1,...9) and non-digits (everything else).
  3. If the number of digits and non-digits are consecutive fibonnacci numbers, with the number of digits is fibonnacci number f(n) and the number of non-digits is f(n-1) the file is "valid", otherwise it is "Invalid"
  4. Output this information as exactly as shown below.

Example 1:

Digits: 34 Nondigits: 21
Valid program

Example 2:

Digits: 33 Nondigits: 21
Invalid program
\$\endgroup\$
  • \$\begingroup\$ You may want to clarify the order of the consecutive Fibonacci numbers in Rule 3. It is currently a bit ambiguous and possibly opposite to the other question. \$\endgroup\$ – Darren Stone Jan 21 '14 at 1:21
  • 1
    \$\begingroup\$ Also, your examples are contrary to each other: 34 & 21 should not be both valid and invalid. Probably a typo. \$\endgroup\$ – Darren Stone Jan 21 '14 at 1:36
  • \$\begingroup\$ looks good now! :-) \$\endgroup\$ – Darren Stone Jan 21 '14 at 1:45
  • \$\begingroup\$ I see you like my validator. Interesting how my code is forked 5 times... \$\endgroup\$ – Justin Jan 21 '14 at 5:06
  • 1
    \$\begingroup\$ Ouch, that rule about explaining in rhyme; it hurt my brain more than any program I wrote here. \$\endgroup\$ – Justin Jan 21 '14 at 6:13
2
\$\begingroup\$

Ruby, 151

d=[0,0];$<.read.chars{|c|d[c>?/&&c<?:?0:1]+=1};puts"Digits: %d Nondigits: %d"%d
a=b=1;while b<d[0];b=a+a=b end;print ([b,a]==d)??V:"Inv","alid program"
\$\endgroup\$
2
\$\begingroup\$

Java - 334

import java.nio.*;public class a{public static void main(String[]i)throws Exception{String s=new String(Files.readAllBytes(Paths.get(i[0])));int l=s.replaceAll("\\d","").length(),L=s.length()-l,a=1,b=2,c,d=0;while(a<L){if(a==l&&b==L)d=1;c=b;b+=a;a=c;}System.out.printf("Digits: %s Nondigits: %s\n%salid Program",L,l,d==0?"Inv":"V");}}

Ungolfed:

import java.nio.file.*;

public class Testing {

    public static void main(String[] i) throws Exception {
        String s = new String(Files.readAllBytes(Paths.get(i[0])));
        int l = s.replaceAll("\\d", "").length(), L = s.length() - l, a = 1, b = 2, c, d = 0;
        while (a < L) {
            if (a == l && b == L) {
                d = 1;
            }
            c = b;
            b += a;
            a = c;
        }
        System.out.printf("Digits: %s Nondigits: %s\n%salid Program", L, l, d == 0 ? "Inv" : "V");
    }
}

Explanation:

Reads the input from the file

supplied by command line

Puts the contents in a String

oh no! I'm thinking of quines.

Regex swaps digits of that thing

for the one and only empty String.

Then by String#length() I find

the charcount nondigit, yes that kind.

From the length of the first String

I subtract the charcount nondigit thing

to find the char digits count.

Next I sweep it all under the rug

so I can say "Help I'm a bug!".

Then I retrieve it - please have patience.

Now the first terms of the Fibonacci sequence

used to find the rest of the numbers.

What to rhyme with? I'll just use "others".

And when small num is greater than non-digits

I know if it's true, so wait a minute.

Uses printf to format output.

"alid Program" at the start puts

"Inv" or "V" according to the answer

Before is the counts, not one thing fancier

Thank you for lis'ning to this tale

Of the program that validates according to your rules


Whew, it was hard to write that.

I decided to assume the input is from the command line, in the form of a String. Please correct me, because if I can simply take a File as input, I can shorten this by a few chars. Also, I'd like to know if a method is okay.

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

Bash, 244

f=`cat $1`&&d=`sed 's/[0-9]*//g' $1`&&echo Digits: ${#d} Nondigits: $[${#f}-${#d}]]
a=1&&b=1&&while [ $b -lt ${#d} ];do z=$b&&b=$[a+b]&&a=$z;done&&if [ $b -eq ${#d} -a $a -eq $[${#f}-${#d}] ];then echo Valid program;else echo Invalid program;fi

call using ./script filename.

I'm not particularly good with bash and I'm sure there are a few ways to get this smaller.

\$\endgroup\$