# Question
Title: RadioASCII Elements: Output the elements of the periodic table while slowly losing characters
Here is a list of the 118 (current) elements of the periodic table (in a collapsed Stack Snippet for your convenience):

```
Hydrogen
Helium
Lithium
Beryllium
Boron
Carbon
Nitrogen
Oxygen
Fluorine
Neon
Sodium
Magnesium
Aluminium
Silicon
Phosphorus
Sulfur
Chlorine
Argon
Potassium
Calcium
Scandium
Titanium
Vanadium
Chromium
Manganese
Iron
Cobalt
Nickel
Copper
Zinc
Gallium
Germanium
Arsenic
Selenium
Bromine
Krypton
Rubidium
Strontium
Yttrium
Zirconium
Niobium
Molybdenum
Technetium
Ruthenium
Rhodium
Palladium
Silver
Cadmium
Indium
Tin
Antimony
Tellurium
Iodine
Xenon
Caesium
Barium
Lanthanum
Cerium
Praseodymium
Neodymium
Promethium
Samarium
Europium
Gadolinium
Terbium
Dysprosium
Holmium
Erbium
Thulium
Ytterbium
Lutetium
Hafnium
Tantalum
Tungsten
Rhenium
Osmium
Iridium
Platinum
Gold
Mercury
Thallium
Lead
Bismuth
Polonium
Astatine
Radon
Francium
Radium
Actinium
Thorium
Protactinium
Uranium
Neptunium
Plutonium
Americium
Curium
Berkelium
Californium
Einsteinium
Fermium
Mendelevium
Nobelium
Lawrencium
Rutherfordium
Dubnium
Seaborgium
Bohrium
Hassium
Meitnerium
Darmstadtium
Roentgenium
Copernicium
Ununtrium
Flerovium
Ununpentium
Livermorium
Ununseptium
Ununoctium
```

*Note: This list was found by running the following JavaScript code on this Wikipedia page: `[].slice.call($('.wikitable:first tr td:nth-child(3)').map(function(){return this.innerText})).slice(1,-1).join('\n')`*

Your challenge is to output as many of them as possible, in as many languages as possible. This goal is even further complicated by the fact that the radioactive elements are slowly eating away at your remaining usable characters as you go!

## Rules

1. Your answer will consist of 1 to 95 code snippets.
2. Each code snippet must be in a different programming language. For the purpose of this challenge, I'm using a very loose definition of "language": Anything that's not backwards-compatible is a different language. For example, if all Lang A code works in Lang B but Lang B adds more, then they're considered the same language. But Python 2 and Python 3 are considered different, because `print 'foo'` is valid in Python 2 but not in Python 3.
3. The first code snippet may use some or all of the 95 printable ASCII characters. In the second snippet, one ASCII character of your choice will be forbidden. In the third snippet, that character plus one more of your choice must be forbidden. And so on. Tabs and newlines are never forbidden.
4. The forbidden character **must** have been used in the previous snippet, *not* in a comment, string literal, etc.; it must actually get interpreted by the compiler/interpreter. For example, if my first snippet is `print 'Hydrogen'`, I can't make `&` forbidden because I didn't use it. My choices are any of the characters `p`, `r`, `i`, `n`, `t`, , or `'` (I can't use `H`, `y`, `d`, ... because those are in a string literal). The character you choose is from then on forbidden to appear at all in any subsequent snippets.
5. Each code snippet must output a unique element of the periodic table (found in the list above). "Output" can be done by any method you wish: STDOUT, an alert box (ex. in JS), REPL "output" (keep in mind that if it includes quotes, it's invalid), writing to a file, etc.
6. You must either take no input, or an empty string as input (for languages like sed).
7. You may not use built-in functions that return the element name (ex. `ElementData` in Mathematica).

## Formatting

Please format your answer with the following format:

```
### 1. Language A - none forbidden

    code

Optional commentary on this snippet goes here.

### 2. Language B - `a` forbidden

    code

More optional commentary

### 3. Language C - `ab` forbidden

    code

More optional commentary

```

etc.

If backticks (```) are forbidden, simply use two backticks around the list instead. For example, ```ab`cd``` will result in `ab`cd`. (If the backtick is the first or last character, you must also pad the outer backticks with spaces; ex. ``` abc` ``` -\> `abc``.)

## Scoring

The answer with the most programming languages will win. In the event of a tie, the answer with the smallest cumulative character count of all of the programs will win.

---

<sup>This question was inspired by this.</sup>

# Answer
> 17 votes
# 95 languages (all characters used!)

## (TODO: a couple more answers that I have planned out but not implemented)

### 1. COBOL - forbids `A`

```
PROGRAM-ID.g.PRODECURE DIVISION.DISPLAY"Ununtrium".

```

Prints `Ununtrium`.

### 2. REBOL - forbids `B`

```
REBOL[]prin"Tellurium"

```

Prints `Tellurium`.

### 3. bc - forbids `^`

```
a=0^0
"Strontium"

```

Prints `Strontium`.

### 4. D - forbids `D`

```
void main(char[][]D){printf="Ruthenium";}

```

Prints `Ruthenium`.

### 5. Java - forbids `E`

```
enum E{E;{System.out.print("\x41luminium");}}

```

Prints `Aluminium`.

### 6. Scala - forbids `F`

```
val F=print("Plutonium")

```

Prints `Plutonium`.

### 7. Rust - forbids `G`

```
fn main(){let G:u8;print("\x41mericium")}

```

Prints `Americium`.

### 8. Nim - forbids `&`

```
discard 0&0
echo "Neptunium"

```

Prints `Neptunium`.

### 9. C# - forbids `C`

```
class V{static void Main(){System.Console.Write("Neodymium");}}

```

Prints `Neodymium`.

### 10. Burlesque \- forbids `%`

```
,1 1.%vv"Manganese"Q

```

Prints `Manganese`.

### 11. Nemerle - forbids `I`

```
Nemerle.IO.print("Magnesium")

```

Prints `Magnesium`.

### 12. Ada - forbids `J`

```
procedure gnat.io.J is begin put("Palladium");end;

```

Prints `Palladium`.

### 13. Go - forbids `|`

```
package main
func main(){if 1|1>0{print("Germanium")}}

```

Prints `Germanium`.

### 14. K - forbids \`\`\`

```
`0:"Ytterbium"

```

Prints `Ytterbium`.

### 15. Erlang - forbids `/`

```
-module(test).
-export([m/0]).
m()->io:put_chars("\x42eryllium").

```

Prints `Beryllium`.

### 16. Prolog - forbids `:`

```
m:-write('\102erkelium').

```

Prints `Berkelium`.

### 17. Smalltalk - forbids `K`

```
K:=0.'Lanthanum'display

```

Prints `Lanthanum`.

### 18. PARI/GP - forbids `L`

```
print(Potassium)

```

Prints `Potassium`.

### 19. REXX - forbids `M`

```
M=0
say "Tungsten"

```

Prints `Tungsten`.

### 20. LilyPond - forbids `N`

```
#(let((N 0))(print"\x46levorium"))

```

Prints `Flevorium`.

### 21. Arc - forbids `Q`

```
(let Q 1(pr "\x41ntimony"))

```

Prints `Antimony`.

### 22. Common LISP - forbids `R`

```
(let((R 0))(princ"Tantalum"))

```

Prints `Tantalum`.

### 23. Clojure - forbids `U`

```
(def U)(pr'Selenium)

```

Prints `Selenium`.

### 24. Logo - forbids `Z`

```
to Z
end
pr[Scandium]bye

```

Prints `Scandium`.

### 25. Groovy - forbids `W`

```
print"Samarium";W=0

```

Prints `Samarium`.

### 26. Asymptote - forbids `X`

```
write('\x52ubidium');int X=0;

```

Prints `Rubidium`.

### 27. Octave - forbids `Y`

```
Y=0;disp Yttrium

```

Prints `Yttrium`.

### 28. gnuplot - forbids `V`

```
V=0;prin"Vanadium

```

Prints `Vanadium`.

### 29. Kite - forbids `z`

```
z=0;"\x4eobelium"|print;

```

Prints `Nobelium`.

### 30. Squirrel - forbids `_`

```
print("\x4eitrogen");local _=0;

```

Prints `Nitrogen`.

### 31. Curry - forbids `v`

```
v=v;main=putStr"\x4cutetium"

```

Prints `Lutetium`.

### 32. Fortran - forbids `q`

```
q=0;print'("Thallium")';end

```

Prints `Thallium`.

### 33. Pascal - forbids `l`

```
begin;var l:integer;write(#70#114#97#110#99#105#117#109)end.

```

Prints `Francium`.

### 34. PHP - forbids `k`

```
<?=$k="\70\108\117\111\114\105\110\101";

```

Prints `Fluorine`.

### 35. Haskell - forbids `S`

```
main=putStr"Sodium"

```

Prints `Sodium`.

### 36. C++ - forbids `~`

```
#include<cstdio>
main(){~puts("\x41ctinium");}

```

Prints `Actinium`.

### 37. ObjC - forbids `j`

```
main(j){puts("Hydrogen");}

```

Prints `Hydrogen`.

### 38. Lua - forbids `g`

```
print("\65statine")

```

Prints `Astatine`.

### 39. JavaScript - forbids `b`

```
alert("\x43h\x6corine")

```

Alerts `Chlorine`.

### 40. Bash - forbids `h`

```
echo Osmium

```

Prints `Osmium`.

### 41. Cyan - forbids `o`

```
say"Hassium"
o=0

```

Prints `Hassium`.

### 42. J - forbids `d`

```
wd'Titanium'

```

Prints `Titanium`.

### 43. Scheme - forbids `x`

```
(let((x 0))(print"Vana\x64ium"))

```

Prints `Vanadium`.

### 44. C - forbids `{`

```
main(){puts("\x55ranium");}

```

Prints `Uranium`.

### 45. FORTH - forbids `m`

```
84 emit
104 emit
111 emit
114 emit
105 emit
117 emit
109 emit

```

Prints `Thorium`.

### 46. BASIC - forbids `T`

```
T$="Tin"
?T$

```

Prints `Tin`.

### 47. Perl 6 - forbids `y`

```
say "\o124\o145\o162\o142\o151\o165\o155"

```

Prints `Terbium`.

### 48. Asdf \- forbids `a`

```
asaasaasssasaasssassaasaasssaasaasssaasaasssaasaasssaasaasssasaasssassaasaasssasaasssassasaasssassasaasssassaasaasssaasaasssasaasssassaasaasssaasaasssasaasssassasaasssassasaasssassaasaasssaasaasssasaasssassasaasssassaasaasssasaasssassasaasssassaasaasssaasaasssasaasssassaasaasssasaasssassaasaasssasaasssassasaasssassaasaasssasaasssassasaasssassasaasssassaasaasssaasaasssasaasssassasaasssassaasaasssasaasssassaasaasssaasaasssasaasssassaasaasssasaasssassasaasssassaasaasssaasaasssaasaasssasaasssassasaasssass

```

Prints `Arsenic`. Generating script.

### 49. Tcl - forbids `s`

```
puts "\123\151\154\151\143\157\156"

```

Prints `Silicon`.

### 50. Perl - forbids `;`

```
print"\122\150\157\144\151\165\155";

```

Prints `Rhodium`.

### 51. Python - forbids `r`

```
print"\103\150\162\157\155\151\165\155"

```

Prints `Chromium`.

### 52. WARP \- forbids `=`

```
=nn0(82(104(110(105(117(109

```

Prints `Rhenium`.

### 53. ETA \- forbids `n`

```
nnOtOe nHHOne enenteht O
nnHHHe nHHtOe enenteht O
nntOHe nHHtne enenteht O
nnHnHe nHHtne enenteht O
nntnte nHHtne enenteht O
nHOHne nHHHte enenteht O

```

Prints `Bromine`.

### 54. Axo \- forbids `\`

```
99*3+(94+8*('u'(93+9*(35*7*('fu'(7+(\

```

Prints `Thulium`.

### 55. Ruby - forbids `t`

```
putc 69
putc 117
putc 114
putc 111
putc 112
putc 105
putc 117
putc 109

```

Prints `Europium`.

### 56. DBFV! \- forbids `u`

```
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u6 u>
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u6 u>
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u3 u>
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u8 u>
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u6 u>
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 u>
u<9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u9 *u6 *u4 u>

```

Prints `Niobium`. Each space is actually a newline.

### 57. Mouse \- forbids `'`

```
77 !' 101 !' 114 !' 99 !' 117 !' 114 !' 121 !'

```

Prints `Mercury`.

### 58. Word \- forbids `f`

```
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.
fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff.

```

Prints `Cadmium`.

### 59. Ftack \- forbids `$`

```
H 109 117 105 104 116 105 $ 1 76

```

Prints `Lithium`.

### 60. WASD \- forbids `e`

We introduce the concept of the *trivial Brainfuck solution* (TBS): we can print any character in 257 Brainfuck commands by incrementing the accumulator *c* times, outputting, then incrementing it (256-*c*) more times to reset it. Repeating this for each character in the string yields the solution. Whenever we have two subprograms `i` and `o` that function exactly like Brainfuck's `+` and `.`, we call the translated TBS the (`i`, `o`)-TBS.

Instead of wrapping around we might be able to set the accumulator to zero after printing using some subprogram `o'`. This is the (`i`, `o'`)-zeroing TBS.

Alternatively, we might have no wrapping but a subprogram `d` that decrements the accumulator. This is a the (`i`, `o`, `d`)-TBS.

For WASD a (`w`, `e`)-TBS prints `Silver`.

### 61. URSL \- forbids `w`

A (`i1`, `w1`, `c1`)-TBS prints `Krypton`.

### 62. Emmental \- forbids `#`

```
#73#114#105#100#105#117#109

```

Prints `Iridium`.

### 63. Owl \- forbids `?`

```
0[]?83)117)108)102)117)114)

```

Prints `Sulfur`.

### 64. RUBE \- forbids `)`

```
    +   +   +       +
 8478 666 667 6965767 6 )
 cccccccccccccccccccccccc

 ........................
O
c
.

```

Prints `Holmium`.

### 65. Headsecks \- forbids `(`

A (`(`, `"`)-TBS prints `Bohrium`.

### 66. FALSE \- forbids `[`

```
[]!71,97,108,105,117,109,

```

Prints `Gallium`.

### 67. Betterave \- forbids `-`

```
,-,++66,-,+8,+5,+*55,*8958

```

Prints `Hafnium`.

### 68. Kipple \- forbids `>`

```
70>o 101>o 114>o 109>o 105>o 117>o 109>o

```

Prints `Fermium`.

### 69. GolfScript \- forbids `]`

```
68]117]98]110]105]117]109]""^

```

Prints `Dubnium`.

### 70. FlogScript \- forbids `"`

```
67"P.97"P.108"P.99"P.105"P.117"P.109"P.

```

Prints `Calcium`.

### 71. OOo CODE \- forbids `p`

A (`PpP`, `PPp`)-TBS prints `Bismuth`.

### 72. dc \- forbids `P`

```
67P97P100P109P105P117P109P

```

Prints `Cadmium`.

### 73. Capuirequiem \- forbids `O`

```
82O97O100O105O117O109O

```

Prints `Radium`.

### 74. BitChanger \- forbids `}`

```
TODO

```

Prints `Cobalt`.

### 75. Vrejvax \- forbids `<`

```
TODO

```

Prints `Cerium`.

### 76. Fueue \- forbids `H`

```
80 111 108 111 110 105 117 109 H

```

Prints `Polonium`.

### 77. Pi \- forbids `6`

Run `bf2pi` from the wiki article on a trivial Brainfuck solution to print `Xenon`.

### 78. CJam \- forbids `5`

A (`1+`, `c 0`)-zeroing TBS (with `0` prepended) prints `Nickel`.

### 79. Wordfuck \- forbids `9`

A (`9999`, `99`)-TBS prints `Carbon`.

### 80. Lenguage \- forbids `7`

```
≈ 3^(257*4*3) sevens

```

See 91-94 (use only `7`.) Prints `Radon`.

### 81. Binaryfuck (hexadecimal) \- forbids `4`

```
TODO

```

Prints `Barium`.

### 82. CaneCode \- forbids `8`

A (`1`, `8`)-TBS prints `Iodine`.

### 83. Numberwang \- forbids `3`

A (`2`, `3`)-TBS prints `Indium`, but `2` decrements instead of incrementing, so subtract each character code from 256 first.

### 84. ferNANDo \- forbids `2`

```
1 1 1
2 1 2 2 2 2 2 1
2 1 1 1 2 2 1 2
2 1 1 2 2 1 1 1
2 1 1 2 1 1 1 1
2 1 1 2 1 1 1 2

```

Prints `Argon`.

### 85. Unefunge-98 \- forbids `@`

Prepending `0` to a (`1+`, `,0`)-zeroing TBS, and appending `@`, prints `Helium`.

### 86. Whirl \- forbids `1`

Prepending `One Load Zero` to an (`Add`, `AscIO Zero`)-zeroing TBS prints `Boron`.

### 87. ReverseFuck \- forbids `,`

A (`-`, `,`)-TBS prints `Erbium`.

### 88. Brainfuck \- forbids `+`

A (`+`, `.`)-TBS prints `Curium`.

### 89. Deadfish~ \- forbids `c`

An (`i`, `c`)-TBS prints `Copper`.

### 90. Iota \- forbids `i`

We compute a Church-numeral base-256-decoding to `Zinc` to make up for Iota's lack of IO. Define

```
succ = ***i*i*i*ii***i*i*i*ii**i*i*ii*i*i*i*ii*i*i*ii

```

Then the solution is 1516858978 repetitions of `succ` followed by `*ii`, for a total length of 69775512991 bytes.

### Unary-like programs

The following four solutions (and 70) are similar: they all consist of approximately 3^(257\*4\*3) repetitions of the character they forbid (except Ellipsis is thrice as long). The exact value is decided by converting the TBS to octal as described on the wiki.

### 91. Ellipsis \- forbids `.`

```
≈ 3^(257*4*3+1) periods

```

Prints `Neon`.

### 92. Ecstatic \- forbids `!`

```
≈ 3^(257*4*3) exclamation marks

```

Prints `Lead`.

### 93. MGIFOS \- forbids `*`

```
≈ 3^(257*4*3) asterisks

```

Prints `Iron`.

### 94. Unary \- forbids `0`

```
≈ 3^(257*4*3) zeros

```

Prints `Gold`.

### 95. Whitespace \- forbids space

The Whitespace program generated by this Python script:

```
import sys
for c in 'Oxygen':
    print '   ' + ''.join(' \t'[int(b)] for b in bin(ord(c))[2:])
    sys.stdout.write('\t\n  ')
print '\n\n'

```

prints `Oxygen`.

# Answer
> 18 votes
# 51 Languages

I might add to this later, but here are 51 languages.

### 1. Java - none forbidden

```
public class p{public static void main(String[]J){System.out.println("Tellurium");}}

```

### 2. C++ - `J` forbidden

```
#include<cstdio>
main(){int Q=std::puts("Palladium");}

```

### 3. C - `JQ` forbidden

```
main(W){puts("Neodymium");}

```

### 4. D - `JQW` forbidden

```
import std.stdio;void main(string[]z){write("Zirconium");}

```

### 5. Nimrod - `JQWz` forbidden

```
var q="Ruthenium"
echo q

```

### 6. Fortran-95 - `JQWzq` forbidden

```
program Y
print *,"Potassium"
end program Y

```

### 7. Batch - `JQWzqY` forbidden

```
@set @c=Aluminium&echo %@c%

```

### 8. Befunge - `JQWzqY%` forbidden

```
"muinoloP">:#,_@

```

Output Polonium.

### 9. Vala - `JQWzqY#%` forbidden

```
int main(string[]@a){print("Manganese");return 0;}

```

### 10. Bash - `JQWzqY#%@` forbidden

```
cd /usr/bin ~/cake;./echo Germanium

```

### 11. ECMAScript 6 - `JQWzqY#%@~` forbidden

```
alert(`Strontium`)

```

### 12. Perl 5 - `JQWzqY#%@~`` forbidden

```
$_=Magnesium;say

```

### 13. Scala - `JQWzqY#%@~`_` forbidden

```
object e{def main(args:Array[String]){print("\u0059tterbium")}}

```

### 14. Perl 6 - `JQWzqY#%@~`_:` forbidden

```
$j='Lanthanum';say

```

### 15. Python 2 - `JQWzqY#%@~`_:j` forbidden

```
print'Lutetium'

```

### 16. Python 3 - `JQWzqY#%@~`_:jL` forbidden

```
print('Krypton')

```

### 17. PHP - `JQWzqY#%@~`_:jLK` forbidden

```
$n='Berkelium';echo$n;

```

### 18. Pascal - `JQWzqY#%@~`_:jLK$` forbidden

```
Program f(X);begin write('Ununtrium');end.

```

### 19. POGAACK - `JQWzqY#%@~`_:jLK$X` forbidden

```
poock!pogack?poock!pock!pock!pock!pock!pock!pock!pogack!pogaaack!pogaack!pogaack?pogack!poock!pogaaack?pogack?poock!pock!pock!pogack!pogaaack!pock!pock!pock!pock!pogaack!pogaack?pogack!pogaaack!pogaaack?poock!pock!pogack?poock!pogack!pogaaack!pock!pock!pogaack!pogaack?pogack!poock!pogaaack?pogaaack!pock!pock!pock!pock!pock!pock!pock!pock!pock!pock!pock!pock!pock!pogaaack?poock!pock!pock!pogaaack?poock!pock!pock!pock!pock!pock!pock!pock!pogaaack?poock!pock!pogaaack?pogaaack!pock!pock!pock!pock!pock!pock!pock!pogaaack?

```

Prints Hydrogen.

### 20. COW - `JQWzqY#%@~`_:jLK$Xg` forbidden

```
MoOMoOMoOMoOMOOmoOMoOMoOMoOMoOMoOmOoMOomoomoOMOOmoOMoOMoOMoOMoOmOoMOomoomoOMooMoOMOOMOoMOoMOomoOMoOMoOMoOMoOmOomoomoOMooMoOMoOMoOMoOMoOMoOMoOMoOMoOMooMOoMooMOoMOoMOoMOoMOoMooMOoMooMOoMOoMOoMOoMOoMooMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMoOMooMOoMOoMOoMOoMOoMOoMOoMOoMoo

```

Prints Plutonium.

### 21. Blub - `JQWzqY#%@~`_:jLK$XgM` forbidden

```
Blub!Blub!Blub!Blub?Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub.Blub?Blub.Blub.Blub?Blub.Blub?Blub!Blub.Blub?Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub.Blub!Blub!Blub!Blub!Blub!Blub?Blub!Blub!Blub!Blub!Blub!Blub!Blub.Blub?Blub.Blub.Blub?Blub.Blub?Blub!Blub.Blub?Blub!Blub.Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub!Blub.Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub!Blub.Blub!Blub?Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub.Blub?Blub.Blub.Blub?Blub.Blub?Blub!Blub.Blub?Blub!Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub.Blub!Blub.Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub!Blub.

```

Prints Flerovium.

### 22. Ook!- `JQWzqY#%@~`_:jLK$XgMB` forbidden

```
Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook?Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook.Ook?Ook.Ook.Ook?Ook.Ook?Ook!Ook.Ook?Ook.Ook.Ook.Ook.Ook!Ook.Ook!Ook?Ook!Ook!Ook!Ook!Ook!Ook!Ook.Ook?Ook.Ook.Ook?Ook.Ook?Ook!Ook.Ook?Ook.Ook.Ook.Ook.Ook!Ook.Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook!Ook.Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook.Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook!Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook.Ook!Ook.Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook!Ook.

```

Prints Americium.

### 23. Ruby - `JQWzqY#%@~`_:jLK$XgMB!` forbidden

```
def e?()return "Neptunium"end;print e?

```

### 24. Lua - `JQWzqY#%@~`_:jLK$XgMB!?` forbidden

```
f=2*4 if f==8then print("Titanium")end

```

### 25. R - `JQWzqY#%@~`_:jLK$XgMB!?*` forbidden

```
U<-"Rubidium";print(U)

```

### 26. Scheme - `JQWzqY#%@~`_:jLK$XgMB!?*U` forbidden

```
(display "Francium")

```

### 27. TI Basic - `JQWzqY#%@~`_:jLK$XgMB!?*U)` forbidden

```
Disp ("Vanadium"

```

### 28. REXX - `JQWzqY#%@~`_:jLK$XgMB!?*U)(` forbidden

```
do Z=1 to 1
    say 'Europium'
end
return

```

### 29. BASIC (Yabasic) - `JQWzqY#%@~`_:jLK$XgMB!?*U)(Z` forbidden

```
PRINT "Chromium"

```

### 30. Pyth - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI` forbidden

```
|0"Scandium

```

### 31. CJam - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|` forbidden

```
"Nobelium"1\\-

```

### 32. GolfScript - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\` forbidden

```
"Samarium"1/

```

### 33. Brainfuck - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/` forbidden

```
,>-[--->+<]>-----.+[--->++++<]>.-----------.--[--->+<]>-.-----------.+++++.+++++++.--------.

```

Takes an empty string as input.

### 34. Haskell - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,` forbidden

```
'Antimon'++['y']

```

### 35. Deadfish - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[` forbidden

```
iisiiiisiiiiiioiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiioiiiiiiiiioddddddoiiiodddddddddoiiiiiodddddddddo]

```

One of the few of these snippets to output a newline afterwards.

### 36. Rebmu \- `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]` forbidden

```
PR"Tungsten"

```

### 37. Tcl - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P` forbidden

```
puts "Actinium"

```

### 38. There Once was a Fish Named Fred - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"` forbidden

```
a named a a a once was there Fred once a a fish named a a a a a once was was was there Fred once fish was was was was was was was fish a a a a a a a fish was was was was was was was was was fish a a a a a fish was was was was was was was was was was was was fish a a a a a a a a fish

```

Prints Selenium.

### 39. BrainFNORD - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"F` forbidden

```
eris 23 eris eris eris fnord hail pineal 5 fnord eris eris eris eris eris eris eris kallisti 23 eris eris eris fnord hail hail hail hail pineal 5 fnord hail kallisti hail hail hail hail hail hail hail hail hail hail hail kallisti eris eris kallisti eris eris eris kallisti eris eris eris eris eris eris eris eris kallisti eris eris kallisti hail hail hail hail hail hail hail hail hail kallisti

```

Prints Nitrogen.

### 40. Text \- `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fl` forbidden

```
Astatine

```

### 41. J - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln` forbidden

```
'Caesium'

```

### 42. Pi - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'` forbidden

```
3.4743302180342223222232222423222332223225222222427402331802252232322322343223322224434433435

```

Prints Tantalum.

### 43. Marbelous \- `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.` forbidden

```
43686C7072696E65
      --        }0

```

Prints Chlorine. This relies on the use of spaces for empty cells. Marbelous Interpreter

### 44. DNA# - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}` forbidden

```
ATCGGCTAATCGATCGATCGATATATTAATGCGCCGATATATCGGCATGCTAATCGATCGATCGATCGATATATTAATTAATTAATTAATTAATGCGCCGATATATCGGCATATCGATCGATCGATCGATCGATCGATCGGCATATTAATTAATTAATTAATTAATTAATTAATTAATTAATTAATTAGCATGCATATCGATCGATCGGCATATTAATTAATTAATTAATTAATTAATTAATTAATTAATTAATTAATTAGCATATCGATCGATCGATCGATCGATCGATCGATCGGCAT

```

Prints Thallium.

### 45. oOo - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}G` forbidden

```
OoOOoOOoOOoOoOoOoOOoOOoOOoOoooOooOooOooooOoOOoooOooOOoOooOooOoooOoOooOooOooOooOoooooOoOooOoOOoooOooOOoOooOooOooOOoOooOooOOoOooOooOooOooOOoOoOOoOOoOOoOOoOOOoOooOooOooOooOooOooOooOooOooOOo

```

Prints Bromine.

### 46. ABC - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}GO` forbidden

```
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAACAAAAAC

```

Prints Tin. Note that the interpreters on esolang are all unavailable. However, 4chan's implementation written in Scheme works (#59).

### 47. WASD - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}GOC` forbidden

```
w1sssdwwa2dwwwe1sssdwa2dweessesssssssssewwwwwwwwwwwwesssssssse

```

Prints Yttrium.

### 48. Super Stack! - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}GOCw` forbidden

```
99 105 110 101 115 114 65
if outputascii fi

```

Prints Arsenic.

### 49. Golunar - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}GOCws` forbidden

```
1334726751425099782624362025339077479253628945660119316869724137277474322140

```

Prints Lithium.

### 50. Unary - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}GOCws1` forbidden

The source is `0` repeated

```
40732627912143966203790325934799402365062057246763194506454552300861148

```

times.

Prints Hassium.

### 51. Lenguage - `JQWzqY#%@~`_:jLK$XgMB!?*U)(ZI|\/,[]P"Fln'.}GOCws10` forbidden

The source is `>` repeated

```
9305604867582777545366404070305393137665254080212227303922021923795365639900

```

times.

Prints Bohrium.

---

Most of the odd languages used can be found on the esolangs wiki.

Please note that all brainfuck (and brainfuck derivatives) snippets were written with 8-bit cells in mind.

# Answer
> 7 votes
# ~~20~~ 24 languages

Here's something to get the ball rolling. I decided to do the elements in order because I don't know enough languages for the order to matter much.

### 1. C# - none forbidden

```
public class P{public static void Main(){System.Console.Write("Hydrogen");}}

```

### 2. PHP - `W` forbidden

```
echo$e="Helium";

```

### 3. QBasic - `W$` forbidden

```
?"Lithium"

```

### 4. Windows Batch Script - `W$?` forbidden

```
dir>nul&echo Beryllium

```

### 5. Brainf\*** - `W$?&` forbidden

```
++++++[>+++++++++++<-]>.----------[>++<-]-.+++.---.-.

```

Outputs Boron.

### 6. C++ - `W$?&+` forbidden

```
#include<iostream>
main(){std::cout<<"Carbon";}

```

### 7. Befunge - `W$?&+<` forbidden

```
"n eg or ti N">,_@

```

Outputs Nitrogen.

### 8. Bash - `W$?&+<@` forbidden

```
echo Oxygen 2>1

```

### 9. Sisi \- `W$?&+<@>` forbidden

```
9 print "Fluorine"

```

### 10. C - `W$?&+<@>9` forbidden

```
#include"stdio.h"
main(){printf("Neon%c",10);}

```

### 11. Common Lisp - `W$?&+<@>9,` forbidden

```
(format t "~Codium" #\S)

```

### 12. Zephyr \- `W$?&+<@>9,#` forbidden

```
if 1\=0:print"Magnesium";end if

```

### 13. Prolog - `W$?&+<@>9,#\` forbidden

```
:-write('Aluminium').

```

(Test here.)

### 14. Java - `W$?&+<@>9,#\:` forbidden

```
class A{public static void main(String[]a){System.out.print("Silicon");}}

```

### 15. Golfscript - `W$?&+<@>9,#\:.` forbidden

```
];"Phosphorus"

```

### 16. Pyth - `W$?&+<@>9,#\:.]` forbidden

```
|0"Sulfur

```

### 17. ActionScript - `W$?&+<@>9,#\:.]|` forbidden

```
trace("Chlorine");

```

### 18. PowerShell - `W$?&+<@>9,#\:.]|;` forbidden

```
write-host"Argon"

```

Fortunately, PowerShell commands can be written in lowercase, avoiding the forbidden `W`.

### 19. JavaScript - `W$?&+<@>9,#\:.]|;-` forbidden

```
alert("Potassium")

```

### 20. Python 3 - `W$?&+<@>9,#\:.]|;-"` forbidden

```
print('Calcium')

```

### 21. Python 2 - `W$?&+<@>9,#\:.]|;-"(` forbidden

```
print'Scandium'

```

### 22. Perl - `W$?&+<@>9,#\:.]|;-"('` forbidden

```
say q{Titanium}

```

### 23. Ruby - `W$?&+<@>9,#\:.]|;-"('{` forbidden

```
puts %q!Vanadium!

```

### 24. CJam - `W$?&+<@>9,#\:.]|;-"('{!` forbidden

```
67c104c114c111c108)c105c117c108)c

```

Outputs Chromium. `)` increments were used to avoid the forbidden 9 in 109 (`m`).

# Answer
> 4 votes
## 23 Languages

I set out to beat the 20 language answer... and now I can't be bothered to shoot for 52. ;)

### 1. Mathematica - none forbidden

```
J;"Krypton"

```

### 2. Ruby - `J` forbidden

```
K=1;puts 'Vanadium'

```

### 3. Python 2 - `JK` forbidden

```
Q=1;print 'Xenon'

```

### 4. Python 3 - `JKQ` forbidden

```
X=1;print('Osmium')

```

### 5. PHP - `JKQX` forbidden

```
$V=1;echo 'Oxygen';

```

### 6. Julia - `JKQXV` forbidden

```
O=1;println('Ytterbium')

```

### 7. JavaScript - `JKQXVO` forbidden

```
Y=1;alert('Yttrium')

```

### 8. CoffeeScript - `JKQXVOY` forbidden

```
q=1;alert 'Zinc'

```

### 9. C - `JKQXVOYq` forbidden

```
main(Z){printf("Zirconium");}

```

### 10. C++ - `JKQXVOYqZ` forbidden

```
#include <cstdio>
int main(){int x;printf("Lawrencium");}

```

### 11. Matlab - `JKQXVOYqZx` forbidden

```
w=1;'Nickel'

```

### 12. Perl - `JKQXVOYqZxw` forbidden

```
$k=1;print "Berkelium";

```

### 13. Perl 6 - `JKQXVOYqZxwk` forbidden

```
$f=1;say'Darmstadtium';

```

### 14. Java - `JKQXVOYqZxwkf` forbidden

```
public class p{public static void main(String[]v){System.out.println("Dubnium");}}

```

### 15. Marbelous \- `JKQXVOYqZxwkfv` forbidden

```
44797370726F7369756D

```

Prints `Dysprosium`.

### 16. Lua - `JKQXVOYqZxwkfvD` forbidden

```
G=1;print("Erbium")

```

### 17. Octave - `JKQXVOYqZxwkfvDG` forbidden

```
F=1;disp('Einsteinium');

```

### 18. Rust - `JKQXVOYqZxwkfvDGF` forbidden

```
fn main(){let E=1;println!("Europium");}

```

### 19. Fortran - `JKQXVOYqZxwkfvDGFE` forbidden

```
print *,"Indium"

```

### 20. CJam - `JKQXVOYqZxwkfvDGFEp` forbidden

```
H;"Iodine"

```

### 21. Golfscript - `JKQXVOYqZxwkfvDGFEpH` forbidden

```
U"Iridium"

```

### 22. Pyth - `JKQXVOYqZxwkfvDGFEpHU` forbidden

```
I1"Iron

```

I *think* this should be

```
if 1:
    print "Iron"

```

### 23. Brainfuck - `JKQXVOYqZxwkfvDGFEpHUI` forbidden

```
++++++++[>+>++>+++>++++>+++++>++++++>+++++++>++++++++>+++++++++>++++++++++>+++++++++++>++++++++++++>+++++++++++++>++++++++++++++>+++++++++++++++>++++++++++++++++<<<<<<<<<<<<<<<<-]>>>>>>>>++.--<<<<<<<<>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<>>>>>>>>>>>>>>++.--<<<<<<<<<<<<<<>>>>>>>>>>>>>>>+.-<<<<<<<<<<<<<<<>>>>>>>>>>>>>>----.++++<<<<<<<<<<<<<<>>>>>>>>>>>>>>----.++++<<<<<<<<<<<<<<>>>>>>>>>>>>>+.-<<<<<<<<<<<<<>>>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<<<>>>>>>>>>>>>>>---.+++<<<<<<<<<<<<<<.

```

Prints `Beryllium`.

# Answer
> 2 votes
## ~~20~~ ~~21~~ 26 languages

Okay, let's see if I can do something out of this, not even trying to aim for top spot... if I can get 20 languages without any mistakes I'll be more than happy.

### 1. JAVA - none forbidden

```
class J{public static void main(String[]a){System.out.print("Hydrogen");}}

```

Prints `Hydrogen`.

### 2. Pascal - `J` forbidden

```
Program H; begin write('Helium'); end.

```

Prints `Helium`.

### 3. C - `JP` forbidden

```
#include <stdio.h> main(){printf("Lithium");}

```

Prints `Lithium`.

### 4. PHP - `JPf` forbidden

```
<?php echo "Beryllium";?>

```

Prints `Beryllium`.

### 5. C# - `JPf?` forbidden

```
using System;class O{static void Main(){Console.Write("Boron");}}

```

Prints `Boron`.

### 6. PROLOG - `JPf?W` forbidden

```
:-initialization(main). main:-write('Carbon').

```

Prints `Carbon` \- tested here.

### 7. JavaScript - `JPf?W'` forbidden

```
<html>
    <script language="javascript" type="text/javascript">
        alert("Nitrogen");
    </script>
</html>

```

Prints `Nitrogen`.

### 8. LOLCODE - `JPf?W'=` forbidden

```
HAI
    VISIBLE "Oxygen"
KTHXBYE

```

Prints `Oxygen`.

### 9. Befunge '93 - `JPf?W'=K` forbidden

```
"eniroulF">:#,_@

```

Prints `Fluorine` \- tested here.

### 10. Visual Basic - `JPf?W'=K@` forbidden

```
Module V
    Sub Main()
        Console.WriteLine("Neon")
    End Sub
End Module

```

Prints `Neon`.

### 11. HTML5 - `JPf?W'=K@M` forbidden

```
Sodium

```

Prints `Sodium` \- inspired by this answer.

### 12. Brainfuck - `JPf?W'=K@M&` forbidden

```
++[---------->+<]>.-[------>+<]>-.++++++.+++++++.---------.[--->+<]>----.----------.++++++++++++.--------.

```

Prints `Magnesium` \- tested here.

### 13. JSFuck - `JPf?W'=K@&M<` forbidden

```
(+![]+[][([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+([][[]]+[])[+[]]+((+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+([![]]+[][[]])[+!+[]+[+[]]]+([][[]]+[])[+[]]+((+[])[([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+([][[]]+[])[+!+[]]+(![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[+!+[]]+([][[]]+[])[+[]]+([][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[][(![]+[])[+[]]+([![]]+[][[]])[+!+[]+[+[]]]+(![]+[])[!+[]+!+[]]+(!![]+[])[+[]]+(!![]+[])[!+[]+!+[]+!+[]]+(!![]+[])[+!+[]]])[+!+[]+[+[]]]+(!![]+[])[+!+[]]]+[])[+!+[]+[+!+[]]]

```

Prints `Aluminium` \- tested here.

### 14. Bash - `JPf?W'=K@&M<[` forbidden

```
#!/bin/bash
echo "Silicon"

```

Prints `Silicon`.

### 15. Assembly NASM - `JPf?W'=K@&M<[!` forbidden

```
section .text
    global _start
section    .data
    msg db  "Phosphorus"
    len equ $ - msg
_start:
    mov edx, len
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    int 0x80
    mov eax, 1
    int 0x80

```

Prints `Phosphorus`\- tested here.

### 16. D - `JPf?W'=K@&M<[!$` forbidden

```
import std.stdio;void main(){write("Chlorine");}

```

Prints `Chlorine`.

### 17. Fortran '95 - `JPf?W'=K@&M<[!$d` forbidden

```
program C
    print *, "Argon"
end program C

```

Prints `Argon` \- tested here.

### 18. Lua - `JPf?W'=K@&M<[!$d*` forbidden

```
print("Sul\x66ur")

```

Prints `Sulfur` \- tested here.

### 19. Golfscript - `JPf?W'=K@&M<[!$dt` forbidden

```
U"\x50o\x74assium"

```

Prints `Potassium` \- tested here.

### 20. Perl 5 - `JPf?W'=K@&M<[!$*dU` forbidden

```
use v5.10;
say "Calciu\x{6d}";

```

Prints `Calcium` \- tested here.

### 21. Nimrod - `JPf?W'=K@&M<[!$*dUu` forbidden

```
echo  "Scan\x64i\x75m"

```

Prints `Scandium`.

### 22. Python - `JPf?W'=K@&M<[!$*dUuh` forbidden

```
print "Titani\165m";

```

Prints `Titanium`.

### 23. Unlambda - `JPf?W'=K@&M<[!$*dUuh;` forbidden

<pre><code>`r````.I.r.o.ni
</code></pre>

Prints `Iron`. - tested here.

### 24. Forth - `JPf?W'=K@&M<[!$*dUuh;``  forbidden

```
\
.( Cobalt) CR

```

Prints `Cobalt` \- tested here.

### 25. Lua - `JPf?W'=K@&M<[!$*dUuh;`\` forbidden

```
print("Nickel")

```

Prints `Nickel` \- tested here

### 26. Emoticon - `JPf?W'=K@&M<[!$*dUuh;`\p` forbidden

```
Zinc :-Q

```

Prints `Zinc`\- tested here

Oh well, I think that's about enough for me.

---
Tags: code-challenge, rosetta-stone
---


title: Counting Grains of Rice

text:
# Question
Title: Counting Grains of Rice
Consider these 10 images of various amounts of uncooked grains of white rice.
**THESE ARE ONLY THUMBNAILS. Click an image to view it at full size.**

**A:**  **B:**  **C:**  **D:**  **E:**

**F:**  **G:**  **H:**  **I:**  **J:**

**Grain Counts:** `A: 3, B: 5, C: 12, D: 25, E: 50, F: 83, G: 120, H:150, I: 151, J: 200`

Notice that...

* **The grains may touch each other but they never overlap.** The layout of grains is never more than one grain high.
* The images have different dimensions but the scale of the rice in all of them is consistent because the camera and background were stationary.
* The grains never go out of bounds or touch the image boundaries.
* The background is always the same consistent shade of yellowish-white.
* Small and large grains are counted alike as one grain each.

These 5 points are guarantees for all images of this sort.

# Challenge

Write a program that takes in such images and, as accurately as possible, counts the number of grains of rice.

Your program should take the filename of the image and print the number of grains it calculates. Your program must work for at least one of these image file formats: JPEG, Bitmap, PNG, GIF, TIFF (right now the images are all JPEGs).

You *may* use image processing and computer vision libraries.

**You may not hardcode the outputs of the 10 example images.** Your algorithm should be applicable to all similar rice-grain images. It should be able to run in less than 5 minutes on a decent modern computer if the image area is less than 2000\*2000 pixels and there are fewer than 300 grains of rice.

# Scoring

For each of the 10 images take the absolute value of the actual number of grains minus the number of grains your program predicts. Sum these absolute values to get your score. The lowest score wins. A score of 0 is perfect.

In case of ties the highest voted answer wins. I may test your program on additional images to verify its validity and accuracy.

# Answer
> 25 votes
# Mathematica, score: 7

```
i = {"https://i.stack.imgur.com/8T6W2.jpg",  "https://i.stack.imgur.com/pgWt1.jpg",
     "https://i.stack.imgur.com/M0K5w.jpg",  "https://i.stack.imgur.com/eUFNo.jpg",
     "https://i.stack.imgur.com/2TFdi.jpg",  "https://i.stack.imgur.com/wX48v.jpg",
     "https://i.stack.imgur.com/eXCGt.jpg",  "https://i.stack.imgur.com/9na4J.jpg",
     "https://i.stack.imgur.com/UMP9V.jpg",  "https://i.stack.imgur.com/nP3Hr.jpg"};

im = Import /@ i;

```

I think the functions' names are descriptive enough:

```
getSatHSVChannelAndBinarize[i_Image]             := Binarize@ColorSeparate[i, "HSB"][[2]]
removeSmallNoise[i_Image]                        := DeleteSmallComponents[i, 100]
fillSmallHoles[i_Image]                          := Closing[i, 1]
getMorphologicalComponentsAreas[i_Image]         := ComponentMeasurements[i, "Area"][[All, 2]]
roundAreaSizeToGrainCount[areaSize_, grainSize_] := Round[areaSize/grainSize]

```

Processing all the pictures at once:

```
counts = Plus @@@
  (roundAreaSizeToGrainCount[#, 2900] & /@
      (getMorphologicalComponentsAreas@
        fillSmallHoles@
         removeSmallNoise@
          getSatHSVChannelAndBinarize@#) & /@ im)

(* Output {3, 5, 12, 25, 49, 83, 118, 149, 152, 202} *)

```

The score is:

```
counts - {3, 5, 12, 25, 50, 83, 120, 150, 151, 200} // Abs // Total
(* 7 *)

```

Here you can see the score sensitivity wrt the grain size used:

# Answer
> 57 votes
# Python, Score: ~~24~~ 16

This solution, like Falko's one, is based on measuring the "foreground" area and dividing it by the average grain area.

In fact, what this program tries to detect is the background, not so much as the foreground. Using the fact that rice grains never touch the image boundary, the program starts by flood-filling white at the top-left corner. The flood-fill algorithm paints adjacent pixels if the difference between theirs and the current pixel's brightness is within a certain threshold, thus adjusting to gradual change in the background color. At the end of this stage, the image might look something like this:

As you can see, it does a pretty good job at detecting the background, but it leaves out any areas that are "trapped" between the grains. We handle these areas by estimating the background brightness at each pixel and painting all equal-or-brighter pixels. This estimation works like so: during the flood-fill stage, we calculate the average background brightness for each row and each column. The estimated background brightness at each pixel is the average of the row and column brightness at that pixel. This produces something like this:

**EDIT:** Finally, the area of each continuous foreground (i.e. non-white) region is divided by the average, precalculated, grain area, giving us an estimate of the grain count in the said region. The sum of these quantities is the result. Initially, we did the same thing for the entire foreground area as a whole, but this approach is, literally, more fine-grained.

---

```
from sys import argv; from PIL import Image

# Init
I = Image.open(argv[1]); W, H = I.size; A = W * H
D = [sum(c) for c in I.getdata()]
Bh = [0] * H; Ch = [0] * H
Bv = [0] * W; Cv = [0] * W

# Flood-fill
Background = 3 * 255 + 1; S = [0]
while S:
    i = S.pop(); c = D[i]
    if c != Background:
        D[i] = Background
        Bh[i / W] += c; Ch[i / W] += 1
        Bv[i % W] += c; Cv[i % W] += 1
        S += [(i + o) % A for o in [1, -1, W, -W] if abs(D[(i + o) % A] - c) < 10]

# Eliminate "trapped" areas
for i in xrange(H): Bh[i] /= float(max(Ch[i], 1))
for i in xrange(W): Bv[i] /= float(max(Cv[i], 1))
for i in xrange(A):
    a = (Bh[i / W] + Bv[i % W]) / 2
    if D[i] >= a: D[i] = Background

# Estimate grain count
Foreground = -1; avg_grain_area = 3038.38; grain_count = 0
for i in xrange(A):
    if Foreground < D[i] < Background:
        S = [i]; area = 0
        while S:
            j = S.pop() % A
            if Foreground < D[j] < Background:
                D[j] = Foreground; area += 1
                S += [j - 1, j + 1, j - W, j + W]
        grain_count += int(round(area / avg_grain_area))

# Output
print grain_count

```

Takes the input filename through the comand line.

## Results

```
      Actual  Estimate  Abs. Error
A         3         3           0
B         5         5           0
C        12        12           0
D        25        25           0
E        50        48           2
F        83        83           0
G       120       116           4
H       150       145           5
I       151       156           5
J       200       200           0
                        ----------
                Total:         16

```

# Answer
> 31 votes
# Python + OpenCV : Score 27

## Horizontal line scanning

Idea : scan the image, one row at a time. For each line, count the number rice grains encountered (by checking if pixel turns black to white or the opposite). If number of grains for the line increase (compared to previous line), it means we encountered a new grain. If that number decrease, it means we passed over a grain. In this case, add +1 to the total result.

```
Number in red = rice grains encountered for that line
Number in gray = total amount of grains encountered (what we are looking for)

```

Because of the way algorithm works, it is important to have a clean, b/w image. Lot of noise produce bad results. First main background is cleaned using floodfill (solution similar to Ell answer) then threshold is applied to produce black and white result.

It is far from perfect, but it produce good results regarding simplicity. There is probably many way to improve it (by providing better b/w image, scanning in other directions (eg : vertical, diagonal) taking the average etc...)

```
import cv2
import numpy
import sys

filename = sys.argv[1]
I = cv2.imread(filename, 0)
h,w = I.shape[:2]
diff = (3,3,3)
mask = numpy.zeros((h+2,w+2),numpy.uint8)
cv2.floodFill(I,mask,(0,0), (255,255,255),diff,diff)
T,I = cv2.threshold(I,180,255,cv2.THRESH_BINARY)
I = cv2.medianBlur(I, 7)

totalrice = 0
oldlinecount = 0
for y in range(0, h):
    oldc = 0
    linecount = 0
    start = 0
    for x in range(0, w):
        c = I[y,x] < 128;
        if c == 1 and oldc == 0:
            start = x
        if c == 0 and oldc == 1 and (x - start) > 10:
            linecount += 1
        oldc = c
    if oldlinecount != linecount:
        if linecount < oldlinecount:
            totalrice += oldlinecount - linecount
        oldlinecount = linecount
print totalrice

```

The errors per image : 0, 0, 0, 3, 0, 12, 4, 0, 7, 1

# Answer
> 25 votes
# Python + OpenCV: Score 84

Here is a first naive attempt. It applies an adaptive threshold with manually tuned parameters, closes some holes with subsequent erosion and dilution and derives the number of grains from the foreground area.

```
import cv2
import numpy as np

filename = raw_input()

I = cv2.imread(filename, 0)
I = cv2.medianBlur(I, 3)
bw = cv2.adaptiveThreshold(I, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 101, 1)

kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (17, 17))
bw = cv2.dilate(cv2.erode(bw, kernel), kernel)

print np.round_(np.sum(bw == 0) / 3015.0)

```

Here you can see the intermediate binary images (black is foreground):

The errors per image are 0, 0, 2, 2, 4, 0, 27, 42, 0 and 7 grains.

# Answer
> 23 votes
## C# + OpenCvSharp, Score: 2

This is my second attempt. It is quite different from my first attempt, which is a lot simpler, so I am posting it as a separate solution.

The basic idea is to identify and label each individual grain by an iterative ellipse fit. Then remove the pixels for this grain from the source, and try to find the next grain, until every pixel has been labeled.

This is not the most pretty solution. It is a giant hog with 600 lines of code. It needs 1.5 minutes for the biggest image. And I really apologize for the messy code.

There are so many parameters and ways to thinker in this thing that I am quite afraid of overfitting my program for the 10 sample images. The final score of 2 is almost definitely a case of overfitting: I have two parameters, `average grain size in pixel`, and `minimum ratio of pixel / elipse_area`, and at the end I simply exhausted all combinations of these two parameters until I got the lowest score. I am not sure whether this is all that kosher with the rules of this challenge.

`average_grain_size_in_pixel = 2530`
`pixel / elipse_area >= 0.73`

But even without these overfitting clutches, the results are quite nice. Without a fixed grain size or pixel-ratio, simply by estimating the average grain size from the training images, the score is still 27.

And I get as the output not only the number, but the actual position, orientation and shape of each grain. there are a small number of mislabeled grains, but overall most of the labels accurately match the real grains:

A B C D E

F G H I J

*(click on each image for the full-sized version)*

After this labeling step, my program looks at each individual grain, and estimates based on the number of pixels and the pixel/ellipse-area ratio, whether this is

* a single grain (+1)
* multiple grains mislabeled as one (+X)
* a blob too small to be a grain (+0)

The error scores for each image are `A:0; B:0; C:0; D:0; E:2; F:0; G:0 ; H:0; I:0, J:0`

However the actual error is probably a little higher. Some errors within the same image cancel each other out. Image H in particular has some badly mislabeled grains, whereas in image E the labels are mostly correct

The concept is a little contrived:

* First the foreground is separated via otsu-thresholding on the saturation channel (see my previous answer for details)
* repeat until no more pixels left:

+ select the largest blob
    + choose 10 random edge pixels on this blob as starting positions for a grain
    + for each starting point

    - assume a grain with height and width 10 pixels at this position.
        - repeat until convergence

        * go radially outwards from this point, at different angles, until you encounter an edge pixel (white-to-black)
            * the found pixels should hopefully be the edge pixels of a single grain. Try to separate inliers from outliers, by discarding pixels that are a more distant from the assumed ellipse than the others
            * repeatedly try to fit an ellipse through a subset of the inliers, keep the best ellipse (RANSACK)
            * update the grain position, orientation, width and height with the found elipse
            * if the grain position does not change significantly, stop
    + among the 10 fitted grains, choose the best grain according to shape, number of edge pixels. Discard the others
    + remove all pixels for this grain from the source image, then repeat
    + finally, go through the list of found grains, and count each grain either as 1 grain, 0 grains (too small) or 2 grains (too big)

One of my main problems was that I did not want to implement a full ellipse-point distance metric, since calculating that in itself is a complicated iterative process. So I used various workarounds using the OpenCV functions Ellipse2Poly and FitEllipse, and the results are not too pretty.

Apparently i also broke the size limit for codegolf.

An answer is limited to 30000 characters, i am currently at 34000. So I'll have to shorten the code below somewhat.

The full code can be seen at http://pastebin.com/RgM7hMxq

Sorry for this, I was not aware that there was a size limit.

```
class Program
{
    static void Main(string[] args)
    {

                // Due to size constraints, I removed the inital part of my program that does background separation. For the full source, check the link, or see my previous program.

                // list of recognized grains
                List<Grain> grains = new List<Grain>();

                Random rand = new Random(4); // determined by fair dice throw, guaranteed to be random

                // repeat until we have found all grains (to a maximum of 10000)
                for (int numIterations = 0; numIterations < 10000; numIterations++ )
                {
                    // erode the image of the remaining foreground pixels, only big blobs can be grains
                    foreground.Erode(erodedForeground,null,7);

                    // pick a number of starting points to fit grains
                    List<CvPoint> startPoints = new List<CvPoint>();
                    using (CvMemStorage storage = new CvMemStorage())
                    using (CvContourScanner scanner = new CvContourScanner(erodedForeground, storage, CvContour.SizeOf, ContourRetrieval.List, ContourChain.ApproxNone))
                    {
                        if (!scanner.Any()) break; // no grains left, finished!

                        // search for grains within the biggest blob first (this is arbitrary)
                        var biggestBlob = scanner.OrderByDescending(c => c.Count()).First();

                        // pick 10 random edge pixels
                        for (int i = 0; i < 10; i++)
                        {
                            startPoints.Add(biggestBlob.ElementAt(rand.Next(biggestBlob.Count())).Value);
                        }
                    }

                    // for each starting point, try to fit a grain there
                    ConcurrentBag<Grain> candidates = new ConcurrentBag<Grain>();
                    Parallel.ForEach(startPoints, point =>
                    {
                        Grain candidate = new Grain(point);
                        candidate.Fit(foreground);
                        candidates.Add(candidate);
                    });

                    Grain grain = candidates
                        .OrderByDescending(g=>g.Converged) // we don't want grains where the iterative fit did not finish
                        .ThenBy(g=>g.IsTooSmall) // we don't want tiny grains
                        .ThenByDescending(g => g.CircumferenceRatio) // we want grains that have many edge pixels close to the fitted elipse
                        .ThenBy(g => g.MeanSquaredError)
                        .First(); // we only want the best fit among the 10 candidates

                    // count the number of foreground pixels this grain has
                    grain.CountPixel(foreground);

                    // remove the grain from the foreground
                    grain.Draw(foreground,CvColor.Black);

                    // add the grain to the colection fo found grains
                    grains.Add(grain);
                    grain.Index = grains.Count;

                    // draw the grain for visualisation
                    grain.Draw(display, CvColor.Random());
                    grain.DrawContour(display, CvColor.Random());
                    grain.DrawEllipse(display, CvColor.Random());

                    //display.SaveImage("10-foundGrains.png");
                }

                // throw away really bad grains
                grains = grains.Where(g => g.PixelRatio >= 0.73).ToList();

                // estimate the average grain size, ignoring outliers
                double avgGrainSize =
                    grains.OrderBy(g => g.NumPixel).Skip(grains.Count/10).Take(grains.Count*9/10).Average(g => g.NumPixel);

                //ignore the estimated grain size, use a fixed size
                avgGrainSize = 2530;

                // count the number of grains, using the average grain size
                double numGrains = grains.Sum(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize));

                // get some statistics
                double avgWidth = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) == 1).Average(g => g.Width);
                double avgHeight = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) == 1).Average(g => g.Height);
                double avgPixelRatio = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) == 1).Average(g => g.PixelRatio);

                int numUndersized = grains.Count(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) < 1);
                int numOversized = grains.Count(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) > 1);

                double avgWidthUndersized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) < 1).Select(g=>g.Width).DefaultIfEmpty(0).Average();
                double avgHeightUndersized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) < 1).Select(g => g.Height).DefaultIfEmpty(0).Average();
                double avgGrainSizeUndersized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) < 1).Select(g => g.NumPixel).DefaultIfEmpty(0).Average();
                double avgPixelRatioUndersized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) < 1).Select(g => g.PixelRatio).DefaultIfEmpty(0).Average();

                double avgWidthOversized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) > 1).Select(g => g.Width).DefaultIfEmpty(0).Average();
                double avgHeightOversized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) > 1).Select(g => g.Height).DefaultIfEmpty(0).Average();
                double avgGrainSizeOversized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) > 1).Select(g => g.NumPixel).DefaultIfEmpty(0).Average();
                double avgPixelRatioOversized = grains.Where(g => Math.Round(g.NumPixel * 1.0 / avgGrainSize) > 1).Select(g => g.PixelRatio).DefaultIfEmpty(0).Average();

                Console.WriteLine("===============================");
                Console.WriteLine("Grains: {0}|{1:0.} of {2} (e{3}), size {4:0.}px, {5:0.}x{6:0.}  {7:0.000}  undersized:{8}  oversized:{9}   {10:0.0} minutes  {11:0.0} s per grain",grains.Count,numGrains,expectedGrains[fileNo],expectedGrains[fileNo]-numGrains,avgGrainSize,avgWidth,avgHeight, avgPixelRatio,numUndersized,numOversized,watch.Elapsed.TotalMinutes, watch.Elapsed.TotalSeconds/grains.Count);

                // draw the description for each grain
                foreach (Grain grain in grains)
                {
                    grain.DrawText(avgGrainSize, display, CvColor.Black);
                }

                display.SaveImage("10-foundGrains.png");
                display.SaveImage("X-" + file + "-foundgrains.png");
            }
        }
    }
}

public class Grain
{
    private const int MIN_WIDTH = 70;
    private const int MAX_WIDTH = 130;
    private const int MIN_HEIGHT = 20;
    private const int MAX_HEIGHT = 35;

    private static CvFont font01 = new CvFont(FontFace.HersheyPlain, 0.5, 1);
    private Random random = new Random(4); // determined by fair dice throw; guaranteed to be random

    /// <summary> center of grain </summary>
    public CvPoint2D32f Position { get; private set; }
    /// <summary> Width of grain (always bigger than height)</summary>
    public float Width { get; private set; }
    /// <summary> Height of grain (always smaller than width)</summary>
    public float Height { get; private set; }

    public float MinorRadius { get { return this.Height / 2; } }
    public float MajorRadius { get { return this.Width / 2; } }
    public double Angle { get; private set; }
    public double AngleRad { get { return this.Angle * Math.PI / 180; } }

    public int Index { get; set; }
    public bool Converged { get; private set; }
    public int NumIterations { get; private set; }
    public double CircumferenceRatio { get; private set; }
    public int NumPixel { get; private set; }
    public List<EllipsePoint> EdgePoints { get; private set; }
    public double MeanSquaredError { get; private set; }
    public double PixelRatio { get { return this.NumPixel / (Math.PI * this.MajorRadius * this.MinorRadius); } }
    public bool IsTooSmall { get { return this.Width < MIN_WIDTH || this.Height < MIN_HEIGHT; } }

    public Grain(CvPoint2D32f position)
    {
        this.Position = position;
        this.Angle = 0;
        this.Width = 10;
        this.Height = 10;
        this.MeanSquaredError = double.MaxValue;
    }

    /// <summary>  fit a single rice grain of elipsoid shape </summary>
    public void Fit(CvMat img)
    {
        // distance between the sampled points on the elipse circumference in degree
        int angularResolution = 1;

        // how many times did the fitted ellipse not change significantly?
        int numConverged = 0;

        // number of iterations for this fit
        int numIterations;

        // repeat until the fitted ellipse does not change anymore, or the maximum number of iterations is reached
        for (numIterations = 0; numIterations < 100 && !this.Converged; numIterations++)
        {
            // points on an ideal ellipse
            CvPoint[] points;
            Cv.Ellipse2Poly(this.Position, new CvSize2D32f(MajorRadius, MinorRadius), Convert.ToInt32(this.Angle), 0, 359, out points,
                            angularResolution);

            // points on the edge of foregroudn to background, that are close to the elipse
            CvPoint?[] edgePoints = new CvPoint?[points.Length];

            // remeber if the previous pixel in a given direction was foreground or background
            bool[] prevPixelWasForeground = new bool[points.Length];

            // when the first edge pixel is found, this value is updated
            double firstEdgePixelOffset = 200;

            // from the center of the elipse towards the outside:
            for (float offset = -this.MajorRadius + 1; offset < firstEdgePixelOffset + 20; offset++)
            {
                // draw an ellipse with the given offset
                Cv.Ellipse2Poly(this.Position, new CvSize2D32f(MajorRadius + offset, MinorRadius + (offset > 0 ? offset : MinorRadius / MajorRadius * offset)), Convert.ToInt32(this.Angle), 0,
                                359, out points, angularResolution);

                // for each angle
                Parallel.For(0, points.Length, i =>
                {
                    if (edgePoints[i].HasValue) return; // edge for this angle already found

                    // check if the current pixel is foreground
                    bool foreground = points[i].X < 0 || points[i].Y < 0 || points[i].X >= img.Cols || points[i].Y >= img.Rows
                                          ? false // pixel outside of image borders is always background
                                          : img.Get2D(points[i].Y, points[i].X).Val0 > 0;

                    if (prevPixelWasForeground[i] && !foreground)
                    {
                        // found edge pixel!
                        edgePoints[i] = points[i];

                        // if this is the first edge pixel we found, remember its offset. the other pixels cannot be too far away, so we can stop searching soon
                        if (offset < firstEdgePixelOffset && offset > 0) firstEdgePixelOffset = offset;
                    }

                    prevPixelWasForeground[i] = foreground;
                });
            }

            // estimate the distance of each found edge pixel from the ideal elipse
            // this is a hack, since the actual equations for estimating point-ellipse distnaces are complicated
            Cv.Ellipse2Poly(this.Position, new CvSize2D32f(MajorRadius, MinorRadius), Convert.ToInt32(this.Angle), 0, 360,
                            out points, angularResolution);
            var pointswithDistance =
                edgePoints.Select((p, i) => p.HasValue ? new EllipsePoint(p.Value, points[i], this.Position) : null)
                          .Where(p => p != null).ToList();

            if (pointswithDistance.Count == 0)
            {
                Console.WriteLine("no points found! should never happen! ");
                break;
            }

            // throw away all outliers that are too far outside the current ellipse
            double medianSignedDistance = pointswithDistance.OrderBy(p => p.SignedDistance).ElementAt(pointswithDistance.Count / 2).SignedDistance;
            var goodPoints = pointswithDistance.Where(p => p.SignedDistance < medianSignedDistance + 15).ToList();

            // do a sort of ransack fit with the inlier points to find a new better ellipse
            CvBox2D bestfit = ellipseRansack(goodPoints);

            // check if the fit has converged
            if (Math.Abs(this.Angle - bestfit.Angle) < 3 && // angle has not changed much (<3°)
                Math.Abs(this.Position.X - bestfit.Center.X) < 3 && // position has not changed much (<3 pixel)
                Math.Abs(this.Position.Y - bestfit.Center.Y) < 3)
            {
                numConverged++;
            }
            else
            {
                numConverged = 0;
            }

            if (numConverged > 2)
            {
                this.Converged = true;
            }

            //Console.WriteLine("Iteration {0}, delta {1:0.000} {2:0.000} {3:0.000}    {4:0.000}-{5:0.000} {6:0.000}-{7:0.000} {8:0.000}-{9:0.000}",
            //  numIterations, Math.Abs(this.Angle - bestfit.Angle), Math.Abs(this.Position.X - bestfit.Center.X), Math.Abs(this.Position.Y - bestfit.Center.Y), this.Angle, bestfit.Angle, this.Position.X, bestfit.Center.X, this.Position.Y, bestfit.Center.Y);

            double msr = goodPoints.Sum(p => p.Distance * p.Distance) / goodPoints.Count;

            // for drawing the polygon, filter the edge points more strongly
            if (goodPoints.Count(p => p.SignedDistance < 5) > goodPoints.Count / 2)
                goodPoints = goodPoints.Where(p => p.SignedDistance < 5).ToList();
            double cutoff = goodPoints.Select(p => p.Distance).OrderBy(d => d).ElementAt(goodPoints.Count * 9 / 10);
            goodPoints = goodPoints.Where(p => p.SignedDistance <= cutoff + 1).ToList();

            int numCertainEdgePoints = goodPoints.Count(p => p.SignedDistance > -2);
            this.CircumferenceRatio = numCertainEdgePoints * 1.0 / points.Count();

            this.Angle = bestfit.Angle;
            this.Position = bestfit.Center;
            this.Width = bestfit.Size.Width;
            this.Height = bestfit.Size.Height;
            this.EdgePoints = goodPoints;
            this.MeanSquaredError = msr;

        }
        this.NumIterations = numIterations;
        //Console.WriteLine("Grain found after {0,3} iterations, size={1,3:0.}x{2,3:0.}   pixel={3,5}    edgePoints={4,3}   msr={5,2:0.00000}", numIterations, this.Width,
        //                        this.Height, this.NumPixel, this.EdgePoints.Count, this.MeanSquaredError);
    }

    /// <summary> a sort of ransakc fit to find the best ellipse for the given points </summary>
    private CvBox2D ellipseRansack(List<EllipsePoint> points)
    {
        using (CvMemStorage storage = new CvMemStorage(0))
        {
            // calculate minimum bounding rectangle
            CvSeq<CvPoint> fullPointSeq = CvSeq<CvPoint>.FromArray(points.Select(p => p.Point), SeqType.EltypePoint, storage);
            var boundingRect = fullPointSeq.MinAreaRect2();

            // the initial candidate is the previously found ellipse
            CvBox2D bestEllipse = new CvBox2D(this.Position, new CvSize2D32f(this.Width, this.Height), (float)this.Angle);
            double bestError = calculateEllipseError(points, bestEllipse);

            Queue<EllipsePoint> permutation = new Queue<EllipsePoint>();
            if (points.Count >= 5) for (int i = -2; i < 20; i++)
                {
                    CvBox2D ellipse;
                    if (i == -2)
                    {
                        // first, try the ellipse described by the boundingg rect
                        ellipse = boundingRect;
                    }
                    else if (i == -1)
                    {
                        // then, try the best-fit ellipsethrough all points
                        ellipse = fullPointSeq.FitEllipse2();
                    }
                    else
                    {
                        // then, repeatedly fit an ellipse through a random sample of points

                        // pick some random points
                        if (permutation.Count < 5) permutation = new Queue<EllipsePoint>(permutation.Concat(points.OrderBy(p => random.Next())));
                        CvSeq<CvPoint> pointSeq = CvSeq<CvPoint>.FromArray(permutation.Take(10).Select(p => p.Point), SeqType.EltypePoint, storage);
                        for (int j = 0; j < pointSeq.Count(); j++) permutation.Dequeue();

                        // fit an ellipse through these points
                        ellipse = pointSeq.FitEllipse2();
                    }

                    // assure that the width is greater than the height
                    ellipse = NormalizeEllipse(ellipse);

                    // if the ellipse is too big for agrain, shrink it
                    ellipse = rightSize(ellipse, points.Where(p => isOnEllipse(p.Point, ellipse, 10, 10)).ToList());

                    // sometimes the ellipse given by FitEllipse2 is totally off
                    if (boundingRect.Center.DistanceTo(ellipse.Center) > Math.Max(boundingRect.Size.Width, boundingRect.Size.Height) * 2)
                    {
                        // ignore this bad fit
                        continue;
                    }

                    // estimate the error
                    double error = calculateEllipseError(points, ellipse);

                    if (error < bestError)
                    {
                        // found a better ellipse!
                        bestError = error;
                        bestEllipse = ellipse;
                    }
                }

            return bestEllipse;
        }
    }

    /// <summary> The proper thing to do would be to use the actual distance of each point to the elipse.
    /// However that formula is complicated, so ...  </summary>
    private double calculateEllipseError(List<EllipsePoint> points, CvBox2D ellipse)
    {
        const double toleranceInner = 5;
        const double toleranceOuter = 10;
        int numWrongPoints = points.Count(p => !isOnEllipse(p.Point, ellipse, toleranceInner, toleranceOuter));
        double ratioWrongPoints = numWrongPoints * 1.0 / points.Count;

        int numTotallyWrongPoints = points.Count(p => !isOnEllipse(p.Point, ellipse, 10, 20));
        double ratioTotallyWrongPoints = numTotallyWrongPoints * 1.0 / points.Count;

        // this pseudo-distance is biased towards deviations on the major axis
        double pseudoDistance = Math.Sqrt(points.Sum(p => Math.Abs(1 - ellipseMetric(p.Point, ellipse))) / points.Count);

        // primarily take the number of points far from the elipse border as an error metric.
        // use pseudo-distance to break ties between elipses with the same number of wrong points
        return ratioWrongPoints * 1000  + ratioTotallyWrongPoints+ pseudoDistance / 1000;
    }

    /// <summary> shrink an ellipse if it is larger than the maximum grain dimensions </summary>
    private static CvBox2D rightSize(CvBox2D ellipse, List<EllipsePoint> points)
    {
        if (ellipse.Size.Width < MAX_WIDTH && ellipse.Size.Height < MAX_HEIGHT) return ellipse;

        // elipse is bigger than the maximum grain size
        // resize it so it fits, while keeping one edge of the bounding rectangle constant

        double desiredWidth = Math.Max(10, Math.Min(MAX_WIDTH, ellipse.Size.Width));
        double desiredHeight = Math.Max(10, Math.Min(MAX_HEIGHT, ellipse.Size.Height));

        CvPoint2D32f average = points.Average();

        // get the corners of the surrounding bounding box
        var corners = ellipse.BoxPoints().ToList();

        // find the corner that is closest to the center of mass of the points
        int i0 = ellipse.BoxPoints().Select((point, index) => new { point, index }).OrderBy(p => p.point.DistanceTo(average)).First().index;
        CvPoint p0 = corners[i0];

        // find the two corners that are neighbouring this one
        CvPoint p1 = corners[(i0 + 1) % 4];
        CvPoint p2 = corners[(i0 + 3) % 4];

        // p1 is the next corner along the major axis (widht), p2 is the next corner along the minor axis (height)
        if (p0.DistanceTo(p1) < p0.DistanceTo(p2))
        {
            CvPoint swap = p1;
            p1 = p2;
            p2 = swap;
        }

        // calculate the three other corners with the desired widht and height

        CvPoint2D32f edge1 = (p1 - p0);
        CvPoint2D32f edge2 = p2 - p0;
        double edge1Length = Math.Max(0.0001, p0.DistanceTo(p1));
        double edge2Length = Math.Max(0.0001, p0.DistanceTo(p2));

        CvPoint2D32f newCenter = (CvPoint2D32f)p0 + edge1 * (desiredWidth / edge1Length) + edge2 * (desiredHeight / edge2Length);

        CvBox2D smallEllipse = new CvBox2D(newCenter, new CvSize2D32f((float)desiredWidth, (float)desiredHeight), ellipse.Angle);

        return smallEllipse;
    }

    /// <summary> assure that the width of the elipse is the major axis, and the height is the minor axis.
    /// Swap widht/height and rotate by 90° otherwise  </summary>
    private static CvBox2D NormalizeEllipse(CvBox2D ellipse)
    {
        if (ellipse.Size.Width < ellipse.Size.Height)
        {
            ellipse = new CvBox2D(ellipse.Center, new CvSize2D32f(ellipse.Size.Height, ellipse.Size.Width), (ellipse.Angle + 90 + 360) % 360);
        }
        return ellipse;
    }

    /// <summary> greater than 1 for points outside ellipse, smaller than 1 for points inside ellipse </summary>
    private static double ellipseMetric(CvPoint p, CvBox2D ellipse)
    {
        double theta = ellipse.Angle * Math.PI / 180;
        double u = Math.Cos(theta) * (p.X - ellipse.Center.X) + Math.Sin(theta) * (p.Y - ellipse.Center.Y);
        double v = -Math.Sin(theta) * (p.X - ellipse.Center.X) + Math.Cos(theta) * (p.Y - ellipse.Center.Y);

        return u * u / (ellipse.Size.Width * ellipse.Size.Width / 4) + v * v / (ellipse.Size.Height * ellipse.Size.Height / 4);
    }

    /// <summary> Is the point on the ellipseBorder, within a certain tolerance </summary>
    private static bool isOnEllipse(CvPoint p, CvBox2D ellipse, double toleranceInner, double toleranceOuter)
    {
        double theta = ellipse.Angle * Math.PI / 180;
        double u = Math.Cos(theta) * (p.X - ellipse.Center.X) + Math.Sin(theta) * (p.Y - ellipse.Center.Y);
        double v = -Math.Sin(theta) * (p.X - ellipse.Center.X) + Math.Cos(theta) * (p.Y - ellipse.Center.Y);

        double innerEllipseMajor = (ellipse.Size.Width - toleranceInner) / 2;
        double innerEllipseMinor = (ellipse.Size.Height - toleranceInner) / 2;
        double outerEllipseMajor = (ellipse.Size.Width + toleranceOuter) / 2;
        double outerEllipseMinor = (ellipse.Size.Height + toleranceOuter) / 2;

        double inside = u * u / (innerEllipseMajor * innerEllipseMajor) + v * v / (innerEllipseMinor * innerEllipseMinor);
        double outside = u * u / (outerEllipseMajor * outerEllipseMajor) + v * v / (outerEllipseMinor * outerEllipseMinor);
        return inside >= 1 && outside <= 1;
    }

    /// <summary> count the number of foreground pixels for this grain </summary>
    public int CountPixel(CvMat img)
    {
        // todo: this is an incredibly inefficient way to count, allocating a new image with the size of the input each time
        using (CvMat mask = new CvMat(img.Rows, img.Cols, MatrixType.U8C1))
        {
            mask.SetZero();
            mask.FillPoly(new CvPoint[][] { this.EdgePoints.Select(p => p.Point).ToArray() }, CvColor.White);
            mask.And(img, mask);
            this.NumPixel = mask.CountNonZero();
        }
        return this.NumPixel;
    }

    /// <summary> draw the recognized shape of the grain </summary>
    public void Draw(CvMat img, CvColor color)
    {
        img.FillPoly(new CvPoint[][] { this.EdgePoints.Select(p => p.Point).ToArray() }, color);
    }

    /// <summary> draw the contours of the grain </summary>
    public void DrawContour(CvMat img, CvColor color)
    {
        img.DrawPolyLine(new CvPoint[][] { this.EdgePoints.Select(p => p.Point).ToArray() }, true, color);
    }

    /// <summary> draw the best-fit ellipse of the grain </summary>
    public void DrawEllipse(CvMat img, CvColor color)
    {
        img.DrawEllipse(this.Position, new CvSize2D32f(this.MajorRadius, this.MinorRadius), this.Angle, 0, 360, color, 1);
    }

    /// <summary> print the grain index and the number of pixels divided by the average grain size</summary>
    public void DrawText(double averageGrainSize, CvMat img, CvColor color)
    {
        img.PutText(String.Format("{0}|{1:0.0}", this.Index, this.NumPixel / averageGrainSize), this.Position + new CvPoint2D32f(-5, 10), font01, color);
    }

}

```

I am a little embarrassed with this solution because a) I am not sure whether it is within the spirit of this challenge, and b) it is too big for a codegolf answer and lacks the elegance of the other solutions.

On the other hand, I am quite happy with the progress I achieved in *labeling* the grains, not merely counting them, so there is that.

# Answer
> 19 votes
# **C++, OpenCV, score: 9**

Basic idea of my method is quite simple - try to erase single grains(and "double grains" - 2 (but not more!) grains, close to each other) from image and then count rest using method based on area (like Falko, Ell and belisarius). Using this approach is a bit better than standard "area method", because it is easier to find good averagePixelsPerObject value.

(1st step)First of all we need to use Otsu binarization on S channel of image in HSV. The next step is using dilate operator to improve quality of extracted foreground. Than we need to find contours. Of course some contours are not grains of rice - we need to delete too small contours (with area smaller then averagePixelsPerObject/4. averagePixelsPerObject is 2855 in my situation). Now finally we can start counting grains :) (2nd step) Finding single and double grains is quite simple - just look in contours list for contours with area within specific ranges - if the contour area is in range, delete it from list and add 1 (or 2 if it was "double" grain) to grains counter. (3rd step) The last step is of course dividing area of remaining contours by averagePixelsPerObject value and add result to grains counter.

Images (for image F.jpg) should show this idea better than words:
1st step (without small contours(noise)):
2nd step - only simple contours:
3rd step - remaining contours:

Here is the code, it's rather ugly, but should work without any problem. Of course OpenCV is required.

```
#include "stdafx.h"

#include <cv.hpp>
#include <cxcore.h>
#include <highgui.h>
#include <vector>

using namespace cv;
using namespace std;

//A: 3, B: 5, C: 12, D: 25, E: 50, F: 83, G: 120, H:150, I: 151, J: 200
const int goodResults[] = {3, 5, 12, 25, 50, 83, 120, 150, 151, 200};
const float averagePixelsPerObject = 2855.0;

const int singleObjectPixelsCountMin = 2320;
const int singleObjectPixelsCountMax = 4060;

const int doubleObjectPixelsCountMin = 5000;
const int doubleObjectPixelsCountMax = 8000;

float round(float x)
{
    return x >= 0.0f ? floorf(x + 0.5f) : ceilf(x - 0.5f);
}

Mat processImage(Mat m, int imageIndex, int &error)
{
    int objectsCount = 0;
    Mat output, thresholded;
    cvtColor(m, output, CV_BGR2HSV);
    vector<Mat> channels;
    split(output, channels);
    threshold(channels[1], thresholded, 0, 255, CV_THRESH_OTSU | CV_THRESH_BINARY);
    dilate(thresholded, output, Mat()); //dilate to imporove quality of binary image
    imshow("thresholded", thresholded);
    int nonZero = countNonZero(output); //not realy important - just for tests
    if (imageIndex != -1)
        cout << "non zero: " << nonZero << ", average pixels per object: " << nonZero/goodResults[imageIndex] << endl;
    else
        cout << "non zero: " << nonZero << endl;

    vector<vector<Point>> contours, contoursOnlyBig, contoursWithoutSimpleObjects, contoursSimple;
    findContours(output, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); //find only external contours
    for (int i=0; i<contours.size(); i++)
        if (contourArea(contours[i]) > averagePixelsPerObject/4.0)
            contoursOnlyBig.push_back(contours[i]); //add only contours with area > averagePixelsPerObject/4 ---> skip small contours (noise)

    Mat bigContoursOnly = Mat::zeros(output.size(), output.type());
    Mat allContours = bigContoursOnly.clone();
    drawContours(allContours, contours, -1, CV_RGB(255, 255, 255), -1);
    drawContours(bigContoursOnly, contoursOnlyBig, -1, CV_RGB(255, 255, 255), -1);
    //imshow("all contours", allContours);
    output = bigContoursOnly;

    nonZero = countNonZero(output); //not realy important - just for tests
    if (imageIndex != -1)
        cout << "non zero: " << nonZero << ", average pixels per object: " << nonZero/goodResults[imageIndex] << " objects: "  << goodResults[imageIndex] << endl;
    else
        cout << "non zero: " << nonZero << endl;

    for (int i=0; i<contoursOnlyBig.size(); i++)
    {
        double area = contourArea(contoursOnlyBig[i]);
        if (area >= singleObjectPixelsCountMin && area <= singleObjectPixelsCountMax) //is this contours a single grain ?
        {
            contoursSimple.push_back(contoursOnlyBig[i]);
            objectsCount++;
        }
        else
        {
            if (area >= doubleObjectPixelsCountMin && area <= doubleObjectPixelsCountMax) //is this contours a double grain ?
            {
                contoursSimple.push_back(contoursOnlyBig[i]);
                objectsCount+=2;
            }
            else
                contoursWithoutSimpleObjects.push_back(contoursOnlyBig[i]); //group of grainss
        }
    }

    cout << "founded single objects: " << objectsCount << endl;
    Mat thresholdedImageMask = Mat::zeros(output.size(), output.type()), simpleContoursMat = Mat::zeros(output.size(), output.type());
    drawContours(simpleContoursMat, contoursSimple, -1, CV_RGB(255, 255, 255), -1);
    if (contoursWithoutSimpleObjects.size())
        drawContours(thresholdedImageMask, contoursWithoutSimpleObjects, -1, CV_RGB(255, 255, 255), -1); //draw only contours of groups of grains
    imshow("simpleContoursMat", simpleContoursMat);
    imshow("thresholded image mask", thresholdedImageMask);
    Mat finalResult;
    thresholded.copyTo(finalResult, thresholdedImageMask); //copy using mask - only pixels whc=ich belongs to groups of grains will be copied
    //imshow("finalResult", finalResult);
    nonZero = countNonZero(finalResult); // count number of pixels in all gropus of grains (of course without single or double grains)
    int goodObjectsLeft = goodResults[imageIndex]-objectsCount;
    if (imageIndex != -1)
        cout << "non zero: " << nonZero << ", average pixels per object: " << (goodObjectsLeft ? (nonZero/goodObjectsLeft) : 0) << " objects left: " << goodObjectsLeft <<  endl;
    else
        cout << "non zero: " << nonZero << endl;
    objectsCount += round((float)nonZero/(float)averagePixelsPerObject);

    if (imageIndex != -1)
    {
        error = objectsCount-goodResults[imageIndex];
        cout << "final objects count: " << objectsCount << ", should be: " << goodResults[imageIndex] << ", error is: " << error <<  endl;
    }
    else
        cout << "final objects count: " << objectsCount << endl;
    return output;
}

int main(int argc, char* argv[])
{
    string fileName = "A";
    int totalError = 0, error;
    bool fastProcessing = true;
    vector<int> errors;

    if (argc > 1)
    {
        Mat m = imread(argv[1]);
        imshow("image", m);
        processImage(m, -1, error);
        waitKey(-1);
        return 0;
    }

    while(true)
    {
        Mat m = imread("images\\" + fileName + ".jpg");
        cout << "Processing image: " << fileName << endl;
        imshow("image", m);
        processImage(m, fileName[0] - 'A', error);
        totalError += abs(error);
        errors.push_back(error);
        if (!fastProcessing && waitKey(-1) == 'q')
            break;
        fileName[0] += 1;
        if (fileName[0] > 'J')
        {
            if (fastProcessing)
                break;
            else
                fileName[0] = 'A';
        }
    }
    cout << "Total error: " << totalError << endl;
    cout << "Errors: " << (Mat)errors << endl;
    cout << "averagePixelsPerObject:" << averagePixelsPerObject << endl;

    return 0;
}

```

If you want to see results of all steps, uncomment all imshow(..,..) function calls and set fastProcessing variable to false. Images(A.jpg, B.jpg,...) should be in directory images. Alternatively course you can give name of one image as a parameter from command line.

Of course if something is unclear i can explain it and/or provide some images/informations.

# Answer
> 13 votes
## C# + OpenCvSharp, score: 71

This is most vexing, I tried to get a solution that actually identifies each grain using watershed, but I just. can't. get. it. to. work.

I settled for a solution that at least separates *some* individual grains and then uses those grains to estimate the average grain size. However so far I cannot beat the solutions with hardcoded grain size.

So, the main highlight of this solution: it does not presume a fixed pixel size for grains, and should work even if the camera is moved or the type of rice is changed.

```
A.jpg; number of grains:    3; expected    3; error    0; pixels per grain: 2525,0;
B.jpg; number of grains:    7; expected    5; error    2; pixels per grain: 1920,0;
C.jpg; number of grains:    6; expected   12; error    6; pixels per grain: 4242,5;
D.jpg; number of grains:   23; expected   25; error    2; pixels per grain: 2415,5;
E.jpg; number of grains:   47; expected   50; error    3; pixels per grain: 2729,9;
F.jpg; number of grains:   65; expected   83; error   18; pixels per grain: 2860,5;
G.jpg; number of grains:  120; expected  120; error    0; pixels per grain: 2552,3;
H.jpg; number of grains:  159; expected  150; error    9; pixels per grain: 2624,7;
I.jpg; number of grains:  141; expected  151; error   10; pixels per grain: 2697,4;
J.jpg; number of grains:  179; expected  200; error   21; pixels per grain: 2847,1;
total error: 71

```

My solution works like this:

Separate the foreground by transforming the image to HSV and applying Otsu thresholding on the saturation channel. This is very simply, works extremely well, and I would recommend this for everyone else who wants to try this challenge:

```
saturation channel                -->         Otsu thresholding

```

--\>

This will cleanly remove the background.

I then additionally removed the *grain shadows* from the foreground, by applying a fixed threshold to the value-channel. (Not sure if that actually helps much, but it was simple enough to add)

Then I apply a distance transform on the foreground image.

and find all local maxima in this distance transform.

This is where my idea breaks down. to avoid getting mutiple local maxima within the same grain, I have to filter a lot. Currently I keep only the strongest maximum within a 45 pixel radius, which means not every grain has a local maximum. And I don't really have a justification for the 45 pixel radius, it was just a value that worked.

(as you can see, those are not nearly enough seeds to account for each grain)

Then I use those maxima as seeds for the watershed algorithm:

The results are *meh*. I was hoping for mostly individual grains, but the clumps are still too big.

Now I identify the smallest blobs, count their average pixel size, and then estimate the number of grains from that. This is *not* what I planned to do at the start, but this was the only way to salvage this.

```
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using OpenCvSharp;

namespace GrainTest2
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] files = new[]
                               {
                                   "sourceA.jpg", "sourceB.jpg", "sourceC.jpg",
                                   "sourceD.jpg", "sourceE.jpg", "sourceF.jpg",
                                   "sourceG.jpg", "sourceH.jpg", "sourceI.jpg", "sourceJ.jpg",
                               };
            int[] expectedGrains = new[]{3, 5, 12, 25, 50, 83, 120, 150, 151, 200,};

            int totalError = 0;
            int totalPixels = 0;

            for(int fileNo = 0;fileNo markers = new List();
                    using (CvMemStorage storage = new CvMemStorage())
                    using (CvContourScanner scanner = new CvContourScanner(localMaxima, storage, CvContour.SizeOf, ContourRetrieval.External,ContourChain.ApproxNone))
                    {
                        // set each local maximum as seed number 25, 35, 45,...
                        // (actual numbers do not matter, chosen for better visibility in the png)
                        int markerNo = 20;
                        foreach (CvSeq c in scanner)
                        {
                            markerNo += 5;
                            markers.Add(markerNo);
                            waterShedMarkers.DrawContours(c, new CvScalar(markerNo), new CvScalar(markerNo), 0, -1);
                        }
                    }
                    waterShedMarkers.SaveImage("08-watershed-seeds.png");

                    source.Watershed(waterShedMarkers);
                    waterShedMarkers.SaveImage("09-watershed-result.png");

                    List pixelsPerBlob = new List();

                    // Terrible hack because I could not get Cv2.ConnectedComponents to work with this openCv wrapper
                    // So I made a workaround to count the number of pixels per blob
                    waterShedMarkers.ConvertScale(waterShedThreshold);
                    foreach (int markerNo in markers)
                    {
                        using (CvMat tmp = new CvMat(waterShedMarkers.Rows, waterShedThreshold.Cols, MatrixType.U8C1))
                        {
                            waterShedMarkers.CmpS(markerNo, tmp, ArrComparison.EQ);
                            pixelsPerBlob.Add(tmp.CountNonZero());

                        }
                    }

                    // estimate the size of a single grain
                    // step 1: assume that the 10% smallest blob is a whole grain;
                    double singleGrain = pixelsPerBlob.OrderBy(p => p).ElementAt(pixelsPerBlob.Count/15);

                    // step2: take all blobs that are not much bigger than the currently estimated singel grain size
                    //        average their size
                    //        repeat until convergence (too lazy to check for convergence)
                    for (int i = 0; i  p  Math.Round(p/singleGrain)).Sum());

                    Console.WriteLine("input: {0}; number of grains: {1,4:0.}; expected {2,4}; error {3,4}; pixels per grain: {4:0.0}; better: {5:0.}", file, numGrains, expectedGrains[fileNo], Math.Abs(numGrains - expectedGrains[fileNo]), singleGrain, pixelsPerBlob.Sum() / 1434.9);

                    totalError += Math.Abs(numGrains - expectedGrains[fileNo]);
                    totalPixels += pixelsPerBlob.Sum();

                    // this is a terrible hack to visualise the estimated number of grains per blob.
                    // i'm too tired to clean it up
                    #region please ignore
                    using (CvMemStorage storage = new CvMemStorage())
                    using (CvMat tmp = waterShedThreshold.Clone())
                    using (CvMat tmpvisu = new CvMat(source.Rows, source.Cols, MatrixType.S8C3))
                    {
                        foreach (int markerNo in markers)
                        {
                            tmp.SetZero();
                            waterShedMarkers.CmpS(markerNo, tmp, ArrComparison.EQ);
                            double curGrains = tmp.CountNonZero() * 1.0 / singleGrain;
                            using (
                                CvContourScanner scanner = new CvContourScanner(tmp, storage, CvContour.SizeOf, ContourRetrieval.External,
                                                                                ContourChain.ApproxNone))
                            {
                                tmpvisu.Set(CvColor.Random(), tmp);
                                foreach (CvSeq c in scanner)
                                {
                                    //tmpvisu.DrawContours(c, CvColor.Random(), CvColor.DarkGreen, 0, -1);
                                    tmpvisu.PutText("" + Math.Round(curGrains, 1), c.First().Value, new CvFont(FontFace.HersheyPlain, 2, 2),
                                                    CvColor.Red);
                                }

                            }

                        }
                        tmpvisu.SaveImage("10-visu.png");
                        tmpvisu.SaveImage("10-visu" + file + ".png");
                    }
                    #endregion

                }

            }
            Console.WriteLine("total error: {0}, ideal Pixel per Grain: {1:0.0}", totalError, totalPixels*1.0/expectedGrains.Sum());

        }
    }
}

```

A small test using a hard-coded pixel-per-grain size of 2544.4 showed a total error of 36, which is still bigger than most other solutions.

# Answer
> 10 votes
# HTML + Javascript: Score 39

The exact values are:

```
Estimated | Actual
        3 |      3
        5 |      5
       12 |     12
       23 |     25
       51 |     50
       82 |     83
      125 |    120
      161 |    150
      167 |    151
      223 |    200

```

It breaks down (isn't accurate) on the larger values.

```
window.onload = function() {
  var $ = document.querySelector.bind(document);
  var canvas = $("canvas"),
    ctx = canvas.getContext("2d");

  function handleFileSelect(evt) {
    evt.preventDefault();
    var file = evt.target.files[0],
      reader = new FileReader();
    if (!file) return;
    reader.onload = function(e) {
      var img = new Image();
      img.onload = function() {
        canvas.width = this.width;
        canvas.height = this.height;
        ctx.drawImage(this, 0, 0);
        start();
      };
      img.src = e.target.result;
    };
    reader.readAsDataURL(file);
  }

  function start() {
    var imgdata = ctx.getImageData(0, 0, canvas.width, canvas.height);
    var data = imgdata.data;
    var background = 0;
    var totalPixels = data.length / 4;
    for (var i = 0; i < data.length; i += 4) {
      var red = data[i],
        green = data[i + 1],
        blue = data[i + 2];
      if (Math.abs(red - 197) < 40 && Math.abs(green - 176) < 40 && Math.abs(blue - 133) < 40) {
        ++background;
        data[i] = 1;
        data[i + 1] = 1;
        data[i + 2] = 1;
      }
    }
    ctx.putImageData(imgdata, 0, 0);
    console.log("Pixels of rice", (totalPixels - background));
    // console.log("Total pixels", totalPixels);
    $("output").innerHTML = "Approximately " + Math.round((totalPixels - background) / 2670) + " grains of rice.";
  }

  $("input").onchange = handleFileSelect;
}
```

```
<input type="file" id="f" />
<canvas></canvas>
<output></output>
```

Explanation: Basically, counts the number of rice pixels and divides it by the average pixels per grain.

# Answer
> 5 votes
An attempt with php, Not the lowest scoring answer but its fairly simple code

SCORE : 31

```
<?php
for($c = 1; $c <= 10; $c++) {
  $a = imagecreatefromjpeg("/tmp/$c.jpg");
  list($width, $height) = getimagesize("/tmp/$c.jpg");
  $rice = 0;
  for($i = 0; $i < $width; $i++) {
    for($j = 0; $j < $height; $j++) {
      $colour = imagecolorat($a, $i, $j);
      if (($colour & 0xFF) < 95) $rice++;
    }
  }
  echo ceil($rice/2966);
}

```

Self scoring

95 is a blue value which seemed to work when testing with GIMP 2966 is average grain size

---
Tags: code-challenge, image-processing, counting
---