Code Golf: Frobenius Number - language-agnostic

Locked. This question and its answers are locked because the question is off-topic but has historical significance. It is not currently accepting new answers or interactions.
Write the shortest program that calculates the Frobenius number for a given set of positive numbers. The Frobenius number is the largest number that cannot be written as a sum of positive multiples of the numbers in the set.
Example: For the set of the Chicken McNuggetTM sizes [6,9,20] the Frobenius number is 43, as there is no solution for the equation a*6 + b*9 + c*20 = 43 (with a,b,c >= 0), and 43 is the largest value with this property.
It can be assumed that a Frobenius number exists for the given set. If this is not the case (e.g. for [2,4]) no particular behaviour is expected.
References:
http://en.wikipedia.org/wiki/Coin_problem
http://mathworld.wolfram.com/FrobeniusNumber.html
[Edit]
I decided to accept the GolfScript version. While the MATHEMATICA version might be considered "technically correct", it would clearly take the fun out of the competition. That said, I'm also impressed by the other solutions, especially Ruby (which was very short for a general purpose language).

Mathematica 0 chars (or 19 chars counting the invoke command)
Invoke wtih
FrobeniusNumber[{a,b,c,...}]
Example
In[3]:= FrobeniusNumber[{6, 9, 20}]
Out[3]= 43
Is it a record? :)

Ruby 100 86 80 chars
(newline not needed)
Invoke with frob.rb 6 9 20
a=$*.map &:to_i;
p ((1..eval(a*"*")).map{|i|a<<i if(a&a.map{|v|i-v})[0];i}-a)[-1]
Works just like the Perl solution (except better:). $* is an array of command line strings; a is the same array as ints, which is then used to collect all the numbers which can be made; eval(a*"*") is the product, the max number to check.
In Ruby 1.9, you can save one additional character in by replacing "*" with ?*.
Edit: Shortened to 86 using Symbol#to_proc in $*.map, inlining m and shortening its calculation by folding the array.
Edit 2: Replaced .times with .map, traded .to_a for ;i.

Mathematica PROGRAM - 28 chars
Well, this is a REAL (unnecessary) program. As the other Mathematica entry shows clearly, you can compute the answer without writing a program ... but here it is
f[x__]:=FrobeniusNumber[{x}]
Invoke with
f[6, 9, 20]
43

GolfScript 47/42 chars
Faster solution (47).
~:+{0+{.1<{$}{1=}if|}/.!1):1\{:X}*+0=-X<}do];X(
Slow solution (42). Checks all values up to the product of every number in the set...
~:+{*}*{0+{.1<{$}{1=}if|}/1):1;}*]-1%.0?>,
Sample I/O:
$ echo "[6 9 20]"|golfscript frobenius.gs
43
$ echo "[60 90 2011]"|golfscript frobenius.gs
58349

Haskell 155 chars
The function f does the work and expects the list to be sorted. For example f [6,9,20] = 43
b x n=sequence$replicate n[0..x]
f a=last$filter(not.(flip elem)(map(sum.zipWith(*)a)(b u(length a))))[1..u] where
h=head a
l=last a
u=h*l-h-l
P.S. since that's my first code golf submission I'm not sure how to handle input, what are the rules?

C#, 360 characters
using System;using System.Linq;class a{static void Main(string[]b)
{var c=(b.Select(d=>int.Parse(d))).ToArray();int e=c[0]*c[1];a:--e;
var f=c.Length;var g=new int[f];g[f-1]=1;int h=1;for(;;){int i=0;for
(int j=0;j<f;j++)i+=c[j]*g[j];if(i==e){goto a;}if(i<e){g[f-1]++;h=1;}
else{if(h>=f){Console.Write(e);return;}for(int k=f-1;k>=f-h;k--)
g[k]=0;g[f-h-1]++;h++;}}}}
I'm sure there's a shorter C# solution than this, but this is what I came up with.
This is a complete program that takes the values as command-line parameters and outputs the result to the screen.

Perl 105 107 110 119 122 127 152 158 characters
Latest edit: Compound assignment is good for you!
$h{0}=$t=1;$t*=$_ for#ARGV;for$x(1..$t){$h{$x}=grep$h{$x-$_},#ARGV}#b=grep!$h{$_},1..$t;print pop#b,"\n"
Explanation:
$t = 1;
$t *= $_ foreach(#ARGV);
Set $t to the product of all of the input numbers. This is our upper limit.
foreach $x (1..$t)
{
$h{$x} = grep {$_ == $x || $h{$x-$_} } #ARGV;
}
For each number from 1 to $t: If it's one of the input numbers, mark it using the %h hash; otherwise, if there is a marked entry from further back (difference being anything in the input), mark this entry. All marked entries are non-candidates for Frobenius numbers.
#b=grep{!$h{$_}}(1..$t);
Extract all UNMARKED entries. These are Frobenius candidates...
print pop #b, "\n"
...and the last of these, the highest, is our Frobenius number.

Haskell 153 chars
A different take on a Haskell solution. I'm a rank novice at Haskell, so I'd be surprised if this couldn't be shortened.
m(x:a)(y:b)
|x==y=x:m a b
|x<y=x:m(y:b)a
|True=y:m(x:a)b
f d=l!!s-1where
l=0:foldl1 m[map(n+)l|n<-d]
g=minimum d
s=until(\n->l!!(n+g)-l!!n==g)(+1)0
Call it with, e.g., f [9,6,20].

FrobeniusScript 5 characters
solve
Sadly there does not yet exist any compiler/interpreter for this language.
No params, the interpreter will handle that:
$ echo solve > myProgram
$ frobeniusScript myProgram
6
9
20
^D
Your answer is: 43
$ exit

Related

Why is this binary scan type specifier escaped with a backslash?

I am updating a project with about a zillion unit tests, so I figured this was a good time to learn Tcl and convert all those tests to Tcl scripts, so that the next time I have to do this, it will be much easier to add new tests. In addition to reading my 2 new books on Tcl, I'm looking over existing scripts online and I ran across this one:
proc do_bincmp_test {testname got expect} {
binary scan $expect \c* expectvals
binary scan $got \c* gotvals
do_test $testname [list set dummy $gotvals] $expectvals
}
and I'm trying to figure out why the type specifier is escaped with a backslash. I wrote this script and ran it:
set expect {Hello World}
binary scan $expect \c* expectvals
puts $expectvals
binary scan $expect c* expectvals
puts $expectvals
=>72 101 108 108 111 32 87 111 114 108 100
=>72 101 108 108 111 32 87 111 114 108 100
I can't find anything in the literature (either online or in the 2 books I have) about escaping type specifiers, just the standard policy that if an escaped character is not one of the special characters that require escaping, the literal
character is used.
So, I figure there are 3 possibilities:
The backslash is an artifact from a much earlier version of Tcl that doesn't do anything now.
The backslash is an ordinary run-of-the-mill brain fart that is harmless.
The backslash is some sort of devilish Tcl subtlety that I am completely overlooking.
I would really like to know which one it is.
I am using Tcl 8.6.7 from IronTcl
According to the Tcl(n) manual page (the specification of the Tcl language core itself), \c has no special meaning (without other escaping) as it is not explicitly listed as one of the backslash-substitution sequences, and so that's equivalent to a plain c character. My guess is that it was put in there out of misunderstanding or as a typo that didn't trigger an error.
It also has no cost apart from slightly more expensive initial parsing. By the time the value hits Tcl's bytecode, that backslash is already gone.

Google Spreadsheet: Count for multiple criteria

K T
WW Data
34 1
34 3
34 4
35 2
35 5
36 1
36 0
How to count number of jobs where DATA>3 for WW=34?
I have tried on several methods but all doesn't work in Google spreadsheet.
method 1: =counta(iferror(filter(T:T;TRIM(T:T)>"3";TRIM(K:K)="34")))
method 2: =ArrayFormula(sum((K:K="34")*(T:T>"3")))
method 3: =ArrayFormula(sum(if(K:K="34",if(T:T>"3")))
method 4: =count(filter(T:T;T:T>"3";K:K="34"))
method 5: =iferror(index(query(K:T,"select count(T) where T>'3' AND K='34'"),2,1),"")
But all doesn't work...
Anyone can help??
I do not understand what you need to count, perhaps the following formulas can help you.
Columns number:
=QUERY(K:T; "SELECT COUNT(T) WHERE K = 34 AND T > 3 LABEL COUNT(T) ''")
You can also use a function like this:
=COUNTA(IFERROR(FILTER(T:T; VALUE(K:K) = 34; VALUE(T:T) > 3); ""))
Pay attention to data types!
Numbers/characters that are surrounded by single/double quotation marks, such as "3" and '3' are string literals, so T>"3" compares the value in T to the string "3", not the number 3.
Therefore, when you want to compare number values, you need to make sure that both your data and the value used for comparison are numbers at the time the actual comparison takes place.
The conversion may be done implicitly by the parser for some data types, (try =NOW()*2 :), or explicitly by you, either because you know the data type is not a number, or you take some sort of precaution with regards to the column's (unknown) data type, like using the VALUE() function, (as suggested by #wchiquito).
Remarks:
Some formats can "break" the VALUE() function as well, making it necessary to take further precautions... but this is beyond the scope of the current discussion.
When you import data from other applications, a column of normal or number values may be converted to string type by either the exporting or the importing application.

Is there any (opposite of newline) char?

Was wondering if we could print from right to left, bottom to top... I got this thought when trying to write a program to print the following square (for an input 'n', here n=4 )
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
This could be solved many ways, by storing into a 2D array and printing the array... (Any language: Perl, C, C++, Java).
The long answer is that you can do whatever the terminal supports. There are many kinds of terminals (or “character output devices”), many of them support cursor motions. (You can see the Termcap Library project to create a picture what different terminal types do.) There is a terminal command for moving up a line, so esentially yes, you should be able to do that. After poking in the termcap database, I came up with the following:
$ printf "\n"; printf '\e[A'; echo Foo
Foo
In other words, the \e[A string has a non-zero chance to get you one line up. On some terminals :)
Baiscly this is possible. But not on an traditional line-based terminal. When accessing the screen pixel based, it's quite easy to solve this problem. At least there is no real counterpart to \n defined in ASCII.
Or maybe this could be archived by changing the input method of the terminal to some culture which reads left to right and bottom to up.

Binary to standard digit?

I'm going to make a computer in Minecraft. I understand how to build a computer where it can make binary operations but I want the outputs to be displayed as standard integer numbers. How you "convert" the binaries into standard digits? Is there any chart for that? And the digits will be shown like in old calculators; with 7 lines.
--
| |
--
| |
--
In electronics, what you need is called a "binary to binary coded decimal" converter. "Binary coded decimal" is the set of bits needed to produce a number on a 7 segment display. Here's a PDF describing how one of these chips works. Page 3 of the PDF shows the truth table needed to do the conversion as well as a picture of all of the NAND gates that implement it in hardware. You can use the truth table to build the set of boolean expressions needed in your program.
0 = 0
1 = 1
10 = 2
11 = 3
100 = 4
101 = 5
110 = 6
111 = 7
...
Do you see the pattern? Here's the formula:
number = 2^0 * (rightmost digit)
+ 2^1 * (rightmost-but-1 digit
+ 2^2 * (rightmost-but-2 digit) + ...
Maybe what you are looking for is called BCD or Binary Coded Decimal. There is a chart and a karnaugh map for it that has been used for decades. a quick Google search for it gave me this technical page
http://circuitscan.homestead.com/files/digelec/bcdto7seg.htm
How are you trying to build the computer?
Maybe that key word can at least help you find what you need. :)
Your problem has two parts:
Convert a binary number into digits, that is do a binary to BCD conversion.
Convert a digit into a set of segments to activate.
For the latter you can use a table that assigns the bitmap of active segments to each digit.
I think's that's two different questions.
There isn't a "binary string of 0/1" to integer conversion built in - you would normally just write your own to loop over the string and detect each power of 2.
YOu can also write your own 7segment LED display - it's a little tricky because it's on multiple lines, but would be an interesting excersize.
Alternatively most GUIs have an LCD font,Qt certainly does

Can this Roman Number to Integer converter code be shorter?

95 bytes currently in python
I,V,X,L,C,D,M,R,r=1,5,10,50,100,500,1000,vars(),lambda x:reduce(lambda T,x:T+R[x]-T%R[x]*2,x,0)
Here is the few test results, it should work for 1 to 3999 (assume input is valid char only)
>>> r("I")
1
>>> r("MCXI")
1111
>>> r("MMCCXXII")
2222
>>> r("MMMCCCXXXIII")
3333
>>> r("MMMDCCCLXXXVIII")
3888
>>> r("MMMCMXCIX")
3999
And this is not duplicate with this, this is reversed one.
So, is it possible to make that shorter in Python, or Other languages like ruby could be done shorter than that?
Shortest solutions from codegolf.com
There was a "Roman to decimal" competition over at Code Golf some time ago. (Well, actually it's still running because they never end.) A Perl golfer by the name of eyepopslikeamosquito decided to win all four languages (Perl, PHP, Python, and Ruby), and so he did. He wrote a fascinating four-part series "The golf course looks great, my swing feels good, I like my chances" (part II, part III, part IV) describing his approaches over at Perl Monks.
Here are his solutions:
Ruby, 53 strokes
n=1;$.+=n/2-n%n=10**(494254%C/9)%4999while C=getc;p$.
Perl, 58 strokes
$\+=$z-2*$z%($z=10**(19&654115/ord)%1645)for<>=~/./g;print
He also has a 53-stroke solution, but it probably doesn't work right now: (it uses the $^T variable during a few second period in 2011!)
$\+=$z-2*$z%($z=10**(7&$^T/ord)%1999)for<>=~/./g;print
PHP, 70 strokes
<?while(A<$c=fgetc(STDIN))$t+=$n-2*$n%$n=md5(o²Ûö¬Ñ.$c)%1858+1?><?=$t;
The six weird characters in the md5(..) are chr(111).chr(178).chr(219).chr(246).chr(172).chr(209) in Perl notation.
Python, 78 strokes
t=p=0
for r in raw_input():n=10**(205558%ord(r)%7)%9995;t+=n-2*p%n;p=n
print t
Python - 94 chars
cheap shot :)
I,V,X,L,C,D=1,5,10,50,100,500
M,R,r=D+D,vars(),lambda x:reduce(lambda T,x:T+R[x]-T%R[x]*2,x,0)
Actually defining my own fromJust is smaller, a total of 98
r=foldl(\t c->t+y c-t`mod`y c*2)0 --34
y x=f$lookup x$zip"IVXLCDM"[1,5,10,50,100,500,1000] --52
f(Just x)=x --12
-- assumes correct input
Haskell gets close.
import Data.Maybe --18
r=foldl(\t c->t+y c-t`mod`y c*2)0 --34
y x=fromJust$lookup x$zip"IVXLCDM"[1,5,10,50,100,500,1000] --59
total bytes = 111
Would be 93 if i didn't need the import for fromJust
Adopting a response from Jon Skeet to a previously asked similar question:
In my custom programming language "CPL1839079", it's 3 bytes:
r=f