www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Lack of `outer` keyword makes inner class dup implossible

reply S. <S._member pathlink.com> writes:
It seems that because inner classes lack an `outer` keyword it is impossible for
them to create a new instance for the purpose of COW when operators like opCom
are called...

sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class BarBar
Jul 14 2006
next sibling parent reply BCS <BCS pathlink.com> writes:
S. wrote:
 It seems that because inner classes lack an `outer` keyword it is impossible
for
 them to create a new instance for the purpose of COW when operators like opCom
 are called...
 
 sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class BarBar
 
 

sudoku.d as in the game? What does the program do? Is it a generator, a solver, or a player? I ask because I have a solver done and would be interested in comparing them.
Jul 14 2006
parent reply S. <user pathlink.com> writes:
On 2006-07-14 13:48:14 -0700, BCS <BCS pathlink.com> said:

 S. wrote:
 It seems that because inner classes lack an `outer` keyword it is 
 impossible for
 them to create a new instance for the purpose of COW when operators like opCom
 are called...
 
 sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class BarBar
 
 

sudoku.d as in the game? What does the program do? Is it a generator, a solver, or a player? I ask because I have a solver done and would be interested in comparing them.

Yes, I'm fiddling around with an analytical solver. Mine currently doesn't solve as many as I would like. I only implemented three elimination methods so far. -S
Jul 14 2006
parent reply "Regan Heath" <regan netwin.co.nz> writes:
------------IvETWbTDu3bk1hw3mOmW4b
Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
Content-Transfer-Encoding: 8bit

On Fri, 14 Jul 2006 17:47:51 -0700, S. <user pathlink.com> wrote:
 On 2006-07-14 13:48:14 -0700, BCS <BCS pathlink.com> said:

 S. wrote:
 It seems that because inner classes lack an `outer` keyword it is  
 impossible for
 them to create a new instance for the purpose of COW when operators  
 like opCom
 are called...
  sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class  
 BarBar

a solver, or a player? I ask because I have a solver done and would be interested in comparing them.

Yes, I'm fiddling around with an analytical solver. Mine currently doesn't solve as many as I would like. I only implemented three elimination methods so far.

I wrote a sudoku solver too. It expects the puzzle in a CSV file, example attached. As far as I know it will solve anything which is 'logically solvable' .. in other words as long as there is always at least one definate next step with no 2+ choices and guessing involved. Regan ------------IvETWbTDu3bk1hw3mOmW4b Content-Disposition: attachment; filename=sudoku.d Content-Type: application/octet-stream; name=sudoku.d Content-Transfer-Encoding: 8bit module sudoku; import std.stdio; import std.stream; import slib; alias slib.remove remove; alias slib.contains contains; class Cell { int[] choices; int value; this() { value = 0; for(int v = 1; v <= 9; v++) choices ~= v; } } Cell[9][9] puzzle; int[][9] rows; int[][9] cols; int[][9] boxs; int assigned; static this() { for(int r = 0; r < 9; r++) { for(int c = 0; c < 9; c++) { puzzle[r][c] = new Cell(); } } for(int i = 0; i < 9; i++) { for(int v = 1; v <= 9; v++) { rows[i] ~= v; cols[i] ~= v; boxs[i] ~= v; } } assigned = 0; } int main(char[][] args) { bool res; if (args.length < 2) { usage(); return 1; } loadPuzzle(args[1]); writefln("PUZZLE"); printPuzzle(); writefln(""); res = solvePuzzle(); if (res) { writefln("SOLUTION"); printPuzzle(); } else { writefln("FAILED"); printDebug(); } writefln(""); return 0; } void usage() { writefln("Usage: sudoku <file>"); } void loadPuzzle(char[] file) { BufferedFile f = new BufferedFile(file); char[] line; int i; for(int r = 0; r < 9; r++) { line = f.readLine(); i = 0; for(int c = 0; c < 9; c++, i++) { if (i < line.length && line[i] != ',') assignValue(r,c,(line[i++]-'0')); } } f.close(); } void printPuzzle() { for(int r = 0; r < 9; r++) { for(int c = 0; c < 9; c++) { if (c) writef(","); if (puzzle[r][c].value) writef(puzzle[r][c].value); else writef("?"); } writefln(""); } } void printDebug() { for(int r = 0; r < 9; r++) { for(int c = 0; c < 9; c++) { writef(puzzle[r][c].choices); } writefln(""); } } void assignValue(int r, int c, int v) { int b = boxn(r,c); puzzle[r][c].choices = null; puzzle[r][c].value = v; assigned++; remove!(int[])(rows[r],v); remove!(int[])(cols[c],v); remove!(int[])(boxs[b],v); for(int i = 0; i < 9; i++) { if (i != c) remove!(int[])(puzzle[r][i].choices,v); if (i != r) remove!(int[])(puzzle[i][c].choices,v); } } bool solvePuzzle() { int prev; while(true) { prev = assigned; scanAll(); for(int r = 0; r < 9; r++) scanRow(r); for(int c = 0; c < 9; c++) scanCol(c); for(int b = 0; b < 9; b++) scanBox(b); if (prev == assigned) return false; if (assigned == 81) break; } return true; } void scanAll() { for(int r = 0; r < 9; r++) { for(int c = 0; c < 9; c++) { if (puzzle[r][c].choices.length == 1) assignValue(r,c,puzzle[r][c].choices[0]); } } } void scanRow(int r) { int[] tmp = rows[r].dup; foreach(int v; tmp) { scanRowValue(r,v); } } void scanRowValue(int r, int v) { int found = 0; int lastc; for(int c = 0; c < 9; c++) { if (puzzle[r][c].value == v || contains!(int[])(puzzle[r][c].choices,v)) { lastc = c; found++; } } if (found == 1) { assignValue(r,lastc,v); } } void scanCol(int c) { int[] tmp = cols[c].dup; foreach(int v; tmp) { scanColValue(c,v); } } void scanColValue(int c, int v) { int found = 0; int lastr; for(int r = 0; r < 9; r++) { if (puzzle[r][c].value == v || contains!(int[])(puzzle[r][c].choices,v)) { lastr = r; found++; } } if (found == 1) { assignValue(lastr,c,v); } } int boxn(int r, int c) { return (r/3)*3 + c/3; } int boxr(int b, int i) { return (b/3)*3 + i/3; } int boxc(int b, int i) { return (b%3)*3 + i%3; } Cell* box(int b, int i) { return &puzzle[boxr(b,i)][boxc(b,i)]; } void scanBox(int b) { int[] tmp = boxs[b].dup; foreach(int v; tmp) { scanBoxValue(b,v); } } void scanBoxValue(int b, int v) { int found = 0; int lasti; for(int i = 0; i < 9; i++) { if (box(b,i).value == v || contains!(int[])(box(b,i).choices,v)) { lasti = i; found++; } } if (found == 1) { assignValue(boxr(b,lasti),boxc(b,lasti),v); } } ------------IvETWbTDu3bk1hw3mOmW4b Content-Disposition: attachment; filename=slib.d Content-Type: application/octet-stream; name=slib.d Content-Transfer-Encoding: 8bit module slib; import std.string; template remove(T:T[]) { void remove(inout T[] a, T v) { for(int i = 0; i < a.length; i++) { if (a[i] != v) continue; if (i < a.length-1) memmove(&a[i],&a[i+1],(a.length-i-1)*T.sizeof); a.length = a.length - 1; i--; } }} template contains(T:T[]) { bool contains(T[] a, T v) { foreach(T c; a) if (c == v) return true; return false; }} ------------IvETWbTDu3bk1hw3mOmW4b Content-Disposition: attachment; filename=140e.csv Content-Type: text/comma-separated-values; name=140e.csv Content-Transfer-Encoding: 8bit ,3,,8,,,1,,2 8,2,,6,,,,9,4 5,,,2,,1,7,, 2,,6,4,1,,,, 1,,3,,,,2,,5 ,,,,5,2,8,,1 ,,5,7,,6,,,9 4,9,,,,3,,1,7 7,,2,,,4,,3, ------------IvETWbTDu3bk1hw3mOmW4b--
Jul 15 2006
next sibling parent reply BCS <BCS pathlink.com> writes:
Regan Heath wrote:
 On Fri, 14 Jul 2006 17:47:51 -0700, S. <user pathlink.com> wrote:
 
 On 2006-07-14 13:48:14 -0700, BCS <BCS pathlink.com> said:

 S. wrote:

 It seems that because inner classes lack an `outer` keyword it is  
 impossible for
 them to create a new instance for the purpose of COW when operators  
 like opCom
 are called...
  sudoku.d(318): outer class Foobar 'this' needed to 'new' nested 
 class  BarBar

generator, a solver, or a player? I ask because I have a solver done and would be interested in comparing them.

Yes, I'm fiddling around with an analytical solver. Mine currently doesn't solve as many as I would like. I only implemented three elimination methods so far.

I wrote a sudoku solver too. It expects the puzzle in a CSV file, example attached. As far as I know it will solve anything which is 'logically solvable' .. in other words as long as there is always at least one definate next step with no 2+ choices and guessing involved. Regan

Mine goes the other direction, only set cells that have only one choice left, when you run out of those, store the state and guess. It uses a stack like system for the states. It was/is solving puzzles in about 2.75 ms. I think it will solve any puzzle that can be solved, and with a little modification, will check if more than one solution exists.
Jul 15 2006
parent reply S. <S._member pathlink.com> writes:
In article <e9c20f$271c$1 digitaldaemon.com>, BCS says...
Regan Heath wrote:
 On Fri, 14 Jul 2006 17:47:51 -0700, S. <user pathlink.com> wrote:
 
 On 2006-07-14 13:48:14 -0700, BCS <BCS pathlink.com> said:

 S. wrote:

 It seems that because inner classes lack an `outer` keyword it is  
 impossible for
 them to create a new instance for the purpose of COW when operators  
 like opCom
 are called...
  sudoku.d(318): outer class Foobar 'this' needed to 'new' nested 
 class  BarBar

generator, a solver, or a player? I ask because I have a solver done and would be interested in comparing them.

Yes, I'm fiddling around with an analytical solver. Mine currently doesn't solve as many as I would like. I only implemented three elimination methods so far.

I wrote a sudoku solver too. It expects the puzzle in a CSV file, example attached. As far as I know it will solve anything which is 'logically solvable' .. in other words as long as there is always at least one definate next step with no 2+ choices and guessing involved. Regan

Mine goes the other direction, only set cells that have only one choice left, when you run out of those, store the state and guess. It uses a stack like system for the states. It was/is solving puzzles in about 2.75 ms. I think it will solve any puzzle that can be solved, and with a little modification, will check if more than one solution exists.

Where's the code? -SC
Jul 17 2006
parent reply BCS <BCS pathlink.com> writes:
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

S. wrote:
 In article <e9c20f$271c$1 digitaldaemon.com>, BCS says...
 
Mine goes the other direction, only set cells that have only one choice 
left, when you run out of those, store the state and guess. It uses a 
stack like system for the states. It was/is solving puzzles in about 
2.75 ms. I think it will solve any puzzle that can be solved, and with a 
little modification, will check if more than one solution exists.

Where's the code? -SC

Jul 17 2006
parent S. <S._member pathlink.com> writes:
In article <e9gh4g$gh$11 digitaldaemon.com>, BCS says...
This is a multi-part message in MIME format.
--------------010201050909040002030603
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit

S. wrote:
 In article <e9c20f$271c$1 digitaldaemon.com>, BCS says...
 
Mine goes the other direction, only set cells that have only one choice 
left, when you run out of those, store the state and guess. It uses a 
stack like system for the states. It was/is solving puzzles in about 
2.75 ms. I think it will solve any puzzle that can be solved, and with a 
little modification, will check if more than one solution exists.

Where's the code? -SC


Very interesting, here's mine. I'm almost embarrased, it's much more complicated than either of your guys'. I've still got alot of work to do on it though.
Jul 17 2006
prev sibling next sibling parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-07-15 02:52:42 -0700, "Regan Heath" <regan netwin.co.nz> said:

 ------------IvETWbTDu3bk1hw3mOmW4b
 Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
 Content-Transfer-Encoding: 8bit
 
 On Fri, 14 Jul 2006 17:47:51 -0700, S. <user pathlink.com> wrote:
 On 2006-07-14 13:48:14 -0700, BCS <BCS pathlink.com> said:
 
 S. wrote:
 It seems that because inner classes lack an `outer` keyword it is  
 impossible for
 them to create a new instance for the purpose of COW when operators  like opCom
 are called...
 sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class  BarBar
 

a solver, or a player? I ask because I have a solver done and would be interested in comparing them.

Yes, I'm fiddling around with an analytical solver. Mine currently doesn't solve as many as I would like. I only implemented three elimination methods so far.

I wrote a sudoku solver too. It expects the puzzle in a CSV file, example attached. As far as I know it will solve anything which is 'logically solvable' .. in other words as long as there is always at least one definate next step with no 2+ choices and guessing involved.

I peaked at your code. From a brief look it doesn't seem that it handles several more advanced analytical techniques. For example if all the posibilities for a number within a box reside on the same row or column, then it is required that the other boxes that contain that column not have it within the column. Etc, There are some really advanced ones like X-Wing etc. I don't fully understand those techniques yet though. I'll post my current code here monday or so. I broke it while implementing constraint propagation for fun.
Jul 16 2006
prev sibling parent S. <S._member pathlink.com> writes:
In article <optcp5p4fx23k2f5 nrage>, Regan Heath says...
------------IvETWbTDu3bk1hw3mOmW4b
Content-Type: text/plain; format=flowed; delsp=yes; charset=iso-8859-15
Content-Transfer-Encoding: 8bit

On Fri, 14 Jul 2006 17:47:51 -0700, S. <user pathlink.com> wrote:
 On 2006-07-14 13:48:14 -0700, BCS <BCS pathlink.com> said:

 S. wrote:
 It seems that because inner classes lack an `outer` keyword it is  
 impossible for
 them to create a new instance for the purpose of COW when operators  
 like opCom
 are called...
  sudoku.d(318): outer class Foobar 'this' needed to 'new' nested class  
 BarBar

a solver, or a player? I ask because I have a solver done and would be interested in comparing them.

Yes, I'm fiddling around with an analytical solver. Mine currently doesn't solve as many as I would like. I only implemented three elimination methods so far.

I wrote a sudoku solver too. It expects the puzzle in a CSV file, example attached. As far as I know it will solve anything which is 'logically solvable' .. in other words as long as there is always at least one definate next step with no 2+ choices and guessing involved. Regan

Wow, your code is kind of tricky. It'll take me a bit to understand all of it. I'll post mine here in a bit. It's ALOT longer though =/ Mine should handle larger grids though, I haven't gotten my hands on any data for 16x16 or whatever yet though.
Jul 17 2006
prev sibling parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"S." <S._member pathlink.com> wrote in message 
news:e98u9d$oqh$1 digitaldaemon.com...
 It seems that because inner classes lack an `outer` keyword it is 
 impossible for
 them to create a new instance for the purpose of COW when operators like 
 opCom
 are called...

It's irritating, isn't it? The workaround is to make the ctor for the inner class take a reference to its owning outer class, then you can use the syntax Inner dup() { Inner n = outerThis.new Inner(outerThis); return n; } That is, you can 'new' the inner class using the outerThis reference. I suppose another way would be to do some terribly ugly, nonportable hacks to _find_ the outer pointer manually. Maybe if we do that, Walter will see that having an 'outer' reference would be useful.
Jul 14 2006
next sibling parent =?ISO-8859-1?Q?Jari-Matti_M=E4kel=E4?= <jmjmak utu.fi.invalid> writes:
Jarrett Billingsley wrote:
 "S." <S._member pathlink.com> wrote in message 
 news:e98u9d$oqh$1 digitaldaemon.com...
 It seems that because inner classes lack an `outer` keyword it is 
 impossible for
 them to create a new instance for the purpose of COW when operators like 
 opCom
 are called...

It's irritating, isn't it? The workaround is to make the ctor for the inner class take a reference to its owning outer class, then you can use the syntax Inner dup() { Inner n = outerThis.new Inner(outerThis); return n; } That is, you can 'new' the inner class using the outerThis reference. I suppose another way would be to do some terribly ugly, nonportable hacks to _find_ the outer pointer manually. Maybe if we do that, Walter will see that having an 'outer' reference would be useful.

Implementation of the inner class always stores the context pointer of the outer class. It could be possible to instantiate yet another inner class by implicitly providing the context pointer of the current outer class to the new inner classes when 'new' is used without a prefix. Again, that's how Java does it. -- Jari-Matti
Jul 14 2006
prev sibling parent reply S. <user pathlink.com> writes:
On 2006-07-14 14:06:35 -0700, "Jarrett Billingsley" <kb3ctd2 yahoo.com> said:

 "S." <S._member pathlink.com> wrote in message 
 news:e98u9d$oqh$1 digitaldaemon.com...
 It seems that because inner classes lack an `outer` keyword it is 
 impossible for
 them to create a new instance for the purpose of COW when operators like opCom
 are called...

It's irritating, isn't it? The workaround is to make the ctor for the inner class take a reference to its owning outer class, then you can use the syntax Inner dup() { Inner n = outerThis.new Inner(outerThis); return n; } That is, you can 'new' the inner class using the outerThis reference. I suppose another way would be to do some terribly ugly, nonportable hacks to _find_ the outer pointer manually. Maybe if we do that, Walter will see that having an 'outer' reference would be useful.

Yes, I thought of that. But Alas, WTF IS THE POINT OF INNER CLASSES IMPLICITLY HAVING THE THING THEN!?!?!?!?!??!!? -S
Jul 14 2006
parent reply Bruno Medeiros <brunodomedeirosATgmail SPAM.com> writes:
S. wrote:
 On 2006-07-14 14:06:35 -0700, "Jarrett Billingsley" <kb3ctd2 yahoo.com> 
 said:
 
 "S." <S._member pathlink.com> wrote in message 
 news:e98u9d$oqh$1 digitaldaemon.com...
 It seems that because inner classes lack an `outer` keyword it is 
 impossible for
 them to create a new instance for the purpose of COW when operators 
 like opCom
 are called...

It's irritating, isn't it? The workaround is to make the ctor for the inner class take a reference to its owning outer class, then you can use the syntax Inner dup() { Inner n = outerThis.new Inner(outerThis); return n; } That is, you can 'new' the inner class using the outerThis reference. I suppose another way would be to do some terribly ugly, nonportable hacks to _find_ the outer pointer manually. Maybe if we do that, Walter will see that having an 'outer' reference would be useful.

Yes, I thought of that. But Alas, WTF IS THE POINT OF INNER CLASSES IMPLICITLY HAVING THE THING THEN!?!?!?!?!??!!? -S

I believe he mentioned that as just a "workaround", a temporary solution, not a final one! -- Bruno Medeiros - CS/E student http://www.prowiki.org/wiki4d/wiki.cgi?BrunoMedeiros#D
Jul 16 2006
parent S. Chancellor <dnewsgr mephit.kicks-ass.org> writes:
On 2006-07-16 06:42:32 -0700, Bruno Medeiros 
<brunodomedeirosATgmail SPAM.com> said:

 S. wrote:
 On 2006-07-14 14:06:35 -0700, "Jarrett Billingsley" <kb3ctd2 yahoo.com> said:
 
 "S." <S._member pathlink.com> wrote in message 
 news:e98u9d$oqh$1 digitaldaemon.com...
 It seems that because inner classes lack an `outer` keyword it is 
 impossible for
 them to create a new instance for the purpose of COW when operators like opCom
 are called...

It's irritating, isn't it? The workaround is to make the ctor for the inner class take a reference to its owning outer class, then you can use the syntax Inner dup() { Inner n = outerThis.new Inner(outerThis); return n; } That is, you can 'new' the inner class using the outerThis reference. I suppose another way would be to do some terribly ugly, nonportable hacks to _find_ the outer pointer manually. Maybe if we do that, Walter will see that having an 'outer' reference would be useful.

Yes, I thought of that. But Alas, WTF IS THE POINT OF INNER CLASSES IMPLICITLY HAVING THE THING THEN!?!?!?!?!??!!? -S

I believe he mentioned that as just a "workaround", a temporary solution, not a final one!

Hehe, I was just venting my frustration :) His solution seems to generate syntax errors when I tried it anyways though =/ -S.
Jul 16 2006