Promising them an increase in their allowance if they get the answer, I offer my two sons, Peter and Paul, the following puzzler:
"I am thinking of a rectangle with integer sides, each of which are greater than one inch. The total perimeter of the rectangle is no greater than eighty inches."
I then whisper the total area to Peter and the total perimeter to Paul. Neither of them are allowed to tell the other what they heard: their job is to work out the rectangle's dimensions.
Their subsequent conversation goes like this:
Peter: Hmmm... I have no idea what the perimeter is.
Paul: I knew you were going to say that. However, I don't know what the area is.
Peter: Still no clue as to the perimeter...
Paul: But now I know what the area is!
Peter: And I know what the perimeter is!
What are the dimensions of the rectangle?
(In reply to
Various comments (spoilers!) by nikki)
[Sorry, I wasn't being sarcastic. You were right all along in the sense that you picked up right away on Paul's subtle first statement, although your first answer was not correct. Remember my comment: "I may be stumbling over that subtle hint 'I knew you were going to say that' by Paul" ? At least I was right about that.]
You were quick to see what eluded me. My original program was not taking that subtle initial remark by Paul into account. When I changed Paul's initial crosscheck to exclude any perimeter which maps to any unique area, I get the answer you get:
perimeter = 22, area = 30.
Imports System
Imports System.IO
Imports System.Text
Imports System.Runtime.InteropServices
Imports System.Math
Module Module1
Sub Main()
Randomize()
Dim strstarttime As String
Dim strendtime As String
Dim strend As String
Dim intsize As Integer
Dim inttabarea(0, 0) As Integer
Dim inttabper(0, 0) As Integer
Dim intloop1 As Integer = 0
Dim intloop2 As Integer = 0
Dim intmax As Integer = 0
Dim strstring As String
Dim strlit As String
strstarttime = TimeOfDay
Console.WriteLine("Start of execution: " & strstarttime)
size_tables(intsize)
ReDim inttabarea(intsize, intsize + 1)
ReDim inttabper(intsize, intsize + 1)
intloop1 = intsize - 1
intloop2 = intsize
gen_tables(inttabarea, inttabper, _
intloop1, intloop2, intmax)
intloop2 = intmax
'Peter: Hmmm... I have no idea what the perimeter is.
singletonpurge(inttabarea, intloop1, intloop2)
'Paul: I knew you were going to say that. However, I 'don't know what the area is.
initialcrosscheck(inttabper, inttabarea, intloop1, intloop2)
singletonpurge(inttabper, intloop1, intloop2)
'Peter: Still no clue as to the perimeter...
crosscheck(inttabarea, inttabper, intloop1, intloop2)
singletonpurge(inttabarea, intloop1, intloop2)
'Paul: But now I know what the area is!
crosscheck(inttabper, inttabarea, intloop1, intloop2)
multiplepurge(inttabper, intloop1, intloop2)
'Peter: And I know what the perimeter is!
crosscheck(inttabarea, inttabper, intloop1, intloop2)
multiplepurge(inttabarea, intloop1, intloop2)
write_answers(inttabarea, inttabper, intloop1, intloop2)
strendtime = TimeOfDay
Console.WriteLine(" ")
Console.WriteLine("Start of execution: " & strstarttime)
strendtime = TimeOfDay
Console.WriteLine("End of execution: " & strendtime)
strend = "?"
Console.WriteLine(" ")
While strend <> "X"
Console.WriteLine("Please enter X to exit program...")
strend = UCase(Console.ReadLine())
End While
End Sub
Sub singletonpurge(ByRef inttab, ByRef intloop1, ByRef intloop2)
Dim intcount As Integer
For index1 As Integer = 0 To intloop1
intcount = 0
For index2 As Integer = 0 To intloop2
If inttab(index1, index2) <> 0 Then
intcount += 1
End If
Next
If intcount < 3 Then
For index2 As Integer = 0 To intloop2
inttab(index1, index2) = 0
Next
End If
Next
End Sub
Sub multiplepurge(ByRef inttab, ByRef intloop1, ByRef intloop2)
Dim intcount As Integer
For index1 As Integer = 0 To intloop1
intcount = 0
For index2 As Integer = 0 To intloop2
If inttab(index1, index2) <> 0 Then
intcount += 1
End If
Next
If intcount <> 2 Then
For index2 As Integer = 0 To intloop2
inttab(index1, index2) = 0
Next
End If
Next
End Sub
Sub initialcrosscheck( _
ByRef inttab1, ByRef inttab2, ByRef intloop1, ByRef intloop2)
Dim intcount As Integer
For index1 As Integer = 0 To intloop1
For index2 As Integer = 1 To intloop2
If inttab1(index1, index2) <> 0 Then
intcount = 0
For index3 As Integer = 0 To intloop1
If inttab1(index1, index2) = inttab2(index3, 0) Then
For index4 As Integer = 1 To intloop2
If inttab2(index3, index4) <> 0 Then
intcount += 1
End If
Next
Exit For
End If
Next
If intcount <= 1 Then
For index5 As Integer = 0 To intloop2
inttab1(index1, index5) = 0
Next
End If
End If
Next
Next
End Sub
Sub crosscheck( _
ByRef inttab1, ByRef inttab2, ByRef intloop1, ByRef intloop2)
Dim intcount As Integer
For index1 As Integer = 0 To intloop1
For index2 As Integer = 1 To intloop2
If inttab1(index1, index2) <> 0 Then
intcount = 0
For index3 As Integer = 0 To intloop1
If inttab1(index1, index2) = inttab2(index3, 0) Then
intcount += 1
Exit For
End If
Next
If intcount = 0 Then
inttab1(index1, index2) = 0
End If
End If
Next
Next
End Sub
Sub size_tables(ByRef intsize)
intsize = 0
For index1 As Integer = 2 To 80
For index2 As Integer = index1 To 80
If (2 * index1) + (2 * index2) <= 80 Then
intsize += 1
End If
Next
Next
End Sub
Sub gen_tables(ByRef inttabarea, ByRef inttabper, _
ByRef intloop1, ByRef intloop2, ByRef intmax)
Dim intarea As Integer
Dim intper As Integer
For index1 As Integer = 0 To intloop1
For index2 As Integer = 0 To intloop2
inttabarea(index1, index2) = 0
inttabper(index1, index2) = 0
Next
Next
For index1 As Integer = 2 To 80
For index2 As Integer = index1 To 80
If (2 * index1) + (2 * index2) <= 80 Then
intarea = index1 * index2
intper = (2 * index1) + (2 * index2)
putintab(intarea, intper, _
inttabarea, intloop1, intloop2, intmax)
putintab(intper, intarea, _
inttabper, intloop1, intloop2, intmax)
End If
Next
Next
intloop2 = intmax
End Sub
Sub putintab(ByRef intqty1, ByRef intqty2, _
ByRef inttab, ByRef intloop1, ByRef intloop2, ByRef intmax)
For index1 As Integer = 0 To intloop1
If inttab(index1, 0) = 0 Then
inttab(index1, 0) = intqty1
inttab(index1, 1) = intqty2
If 1 > intmax Then
intmax = 1
End If
Exit Sub
End If
If inttab(index1, 0) = intqty1 Then
For index2 As Integer = 1 To intloop2
If inttab(index1, index2) = 0 Then
inttab(index1, index2) = intqty2
If index2 > intmax Then
intmax = intqty2
End If
Exit Sub
End If
If inttab(index1, index2) = intqty2 Then
Exit Sub
End If
Next
End If
Next
End Sub
Sub write_answers( _
ByRef inttabarea, ByRef inttabper, ByRef intloop1, ByRef intloop2)
Dim strstring As String
Dim intcount As Integer = 0
Dim objStreamWriter As StreamWriter
Console.WriteLine("Writing anser dataset")
objStreamWriter = _
New StreamWriter("C:\VB.RECTANGULAR.LOGIC")
objStreamWriter.WriteLine(strstring)
For index1 As Integer = 0 To intloop1
If inttabarea(index1, 0) <> 0 Then
strstring = "area: " & inttabarea(index1, 0) & _
" (perimeters: "
For index2 As Integer = 1 To intloop2
If inttabarea(index1, index2) <> 0 Then
strstring &= Str(inttabarea(index1, index2))
End If
Next
strstring &= ")"
objStreamWriter.WriteLine(strstring)
intcount += 1
End If
Next
For index1 As Integer = 0 To intloop1
If inttabper(index1, 0) <> 0 Then
strstring = "perimeter: " & inttabper(index1, 0) & _
" (areas: "
For index2 As Integer = 1 To intloop2
If inttabper(index1, index2) <> 0 Then
strstring &= Str(inttabper(index1, index2))
End If
Next
strstring &= ")"
objStreamWriter.WriteLine(strstring)
intcount += 1
End If
Next
objStreamWriter.Close()
Console.WriteLine(intcount & " records written")
End Sub
End Module
Edited on February 2, 2005, 11:38 am
|
Posted by Penny
on 2005-02-01 16:23:24 |