Kernighans large earthquake problem: Difference between revisions

m
No edit summary
m (→‎{{header|Wren}}: Minor tidy)
 
(4 intermediate revisions by 3 users not shown)
Line 1:
{{task}}
 
[https[w://en.wikipedia.org/wiki/Brian_KernighanBrian Kernighan|Brian Kernighan]], in a [https://www.youtube.com/watch?v=Sg4U4r_AgJU lecture] at the University of Nottingham, described a [https://youtu.be/Sg4U4r_AgJU?t=50s problem] on which this task is based.
 
;Problem:
Line 1,007:
First, with a data file. This adds a fair amount of verbosity to COBOL. For something this one-off, a simpler cut using ACCEPT from standard in is shown.
 
<syntaxhighlight lang="cobolcobolfree">*>
*> Kernighan large earthquake problem
*>
*> Tectonics: cobc -xj kernighan-earth-quakes.cob
*> Kernighan large earthquake problem
*> *> Tectonics: cobc -xj kernighan-earth-quakes.cobtxt with the 3 sample lines
*> ./kernighan-earth-quakes.txt with the 3 sample lines
*>
*> ./kernighan-earth-quakes
>>SOURCE FORMAT IS FREE
*>
IDENTIFICATION DIVISION.
>>SOURCE FORMAT IS FREE
PROGRAM-ID. quakes.
identification division.
program-id. quakes.
 
ENVIRONMENT DIVISION.
environment division.
CONFIGURATION SECTION.
configuration section.
REPOSITORY.
repository.
FUNCTION ALL INTRINSIC.
function all intrinsic.
 
INPUT-OUTPUT SECTION.
input-output section.
FILE-CONTROL.
file-control.
selectSELECT quake-data
ASSIGN assign toTO command-filename
ORGANIZATION IS organizationLINE is line sequentialSEQUENTIAL
STATUS status isIS quake-fd-status.
.
 
DATA DIVISION.
data division.
FILE SECTION.
file section.
fd FD quake-data recordRECORD varyingVARYING dependingDEPENDING onON line-length.
01 data-line pic x PICTURE IS X(32768).
 
WORKING-STORAGE SECTION.
working-storage section.
01 quake-fd-status 01 quake-fd-statusPICTURE picIS xxXX.
88 ok 88 ok values VALUES ARE "00", "01", "02", "03", "04",
"05", "06", "07", "08", "09".
88 no-more 88 no-more value VALUE IS "10".
88 io-error 88 io-error value high VALUE IS HIGH-valueVALUE.
 
01 line-length USAGE IS BINARY-LONG.
01 line-length usage binary-long.
01 date-time PICTURE IS X(10).
01 quake PICTURE IS X(20).
01 magnitude PICTURE IS 99V99.
 
01 command-filename 01 date-timePICTURE picIS xX(1080).
01 quake pic x(20).
01 magnitude pic 99v99.
 
PROCEDURE DIVISION.
01 command-filename pic x(80).
show-big-ones.
procedure division.
show-big-ones.
 
acceptACCEPT command-filename fromFROM commandCOMMAND-lineLINE
ifIF command-filename equalIS EQUAL TO spacesSPACES thenTHEN
moveMOVE "data.txt" toTO command-filename
endEND-ifIF
 
OPEN open inputINPUT quake-data
performPERFORM status-check
ifIF io-error thenTHEN
DISPLAY display trimTRIM(command-filename) " not found" uponUPON syserrSYSERR
gobackGOBACK
endEND-ifIF
 
readREAD quake-data
performPERFORM status-check
PERFORM perform untilUNTIL no-more orOR io-error
unstringUNSTRING data-line delimitedDELIMITED byBY allALL spacesSPACES
intoINTO date-time quake magnitude
endEND-unstringUNSTRING
 
IF magnitude if magnitudeIS greaterGREATER thanTHAN 6
displayDISPLAY date-time spaceSPACE quake spaceSPACE magnitude
endEND-ifIF
 
readREAD quake-data
performPERFORM status-check
endEND-performPERFORM
 
closeCLOSE quake-data
performPERFORM status-check
gobackGOBACK.
*> *> ****
 
status-check.
IF if notNOT ok andAND notNOT no-more thenTHEN *> not normal status, bailing
displayDISPLAY "io error: " quake-fd-status uponUPON syserrSYSERR
setSET io-error toTO trueTRUE
endEND-ifIF
EXIT PARAGRAPH.
 
END end programPROGRAM quakes.</syntaxhighlight>
 
{{output}}
Line 1,110 ⟶ 1,108:
<syntaxhighlight lang="cobol"> *>
*> Tectonics: ./kerighan-earth-quakes <quakes.txt
identificationIDENTIFICATION divisionDIVISION.
programPROGRAM-idID. quakes.
 
dataDATA divisionDIVISION.
 
workingWORKING-storageSTORAGE sectionSECTION.
01 data-line pic x PICTURE IS X(32768).
88 no-more value high VALUE IS HIGH-valuesVALUES.
 
01 date-time pic x PICTURE IS X(10).
01 quake pic x PICTURE IS X(20).
01 magnitude pic 99v99 PICTURE IS 99V99.
 
procedurePROCEDURE divisionDIVISION.
show-big-ones.
 
acceptACCEPT data-line onON exceptionEXCEPTION setSET no-more toTO trueTRUE endEND-acceptACCEPT
performPERFORM untilUNTIL no-more
unstringUNSTRING data-line delimitedDELIMITED byBY allALL spacesSPACES
intoINTO date-time quake magnitude
endEND-unstringUNSTRING
 
ifIF magnitude greaterIS thanGREATER THAN 6
displayDISPLAY date-time spaceSPACE quake spaceSPACE magnitude
endEND-ifIF
 
acceptACCEPT data-line onON exceptionEXCEPTION setSET no-more toTO trueTRUE endEND-acceptACCEPT
endEND-performPERFORM
 
gobackGOBACK.
endEND programPROGRAM quakes.</syntaxhighlight>
 
That cut would be used as <pre>prompt$ ./kernighans-large-earthquakes <quakes.txt</pre>
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
include "file.coh";
 
# Process a file line by line
interface LineCb(line: [uint8]);
sub ForEachLine(fcb: [FCB], cb: LineCb) is
var buf: uint8[256];
var ptr := &buf[0];
var length := FCBExt(fcb);
while length != 0 loop
var ch := FCBGetChar(fcb);
[ptr] := ch;
ptr := @next ptr;
if ch == '\n' then
[ptr] := 0;
ptr := &buf[0];
cb(&buf[0]);
end if;
length := length - 1;
end loop;
end sub;
 
# Get magnitude from line
# Cowgol does not support floating point arithmetic, so the integer and
# fractional parts are returned separately
sub magnitude(line: [uint8]): (i: uint8, frac: uint8) is
i := 0;
frac := 0;
var col: uint8 := 1;
var space: uint8 := 0;
# scan ahead to 3rd column
while col < 3 loop
var ch := [line];
line := @next line;
if ch == 0 then break; end if;
if ch <= ' ' then
while ch <= ' ' and ch != 0 loop
ch := [line];
line := @next line;
end loop;
col := col + 1;
end if;
end loop;
if ch == 0 then
return; # no 3rd column
end if;
line := @prev line;
var n: int32;
var pos: [uint8];
# grab integer part
(n, pos) := AToI(line);
if pos == line then
return; # no value
end if;
i := n as uint8;
if [pos] == '.' then
# grab fractional part
(n, pos) := AToI(@next pos);
frac := n as uint8;
end if;
end sub;
 
# Print any line that has a magnitude > 6
sub PrintIfGt6 implements LineCb is
var i: uint8;
var frac: uint8;
(i, frac) := magnitude(line);
if i > 6 or (i == 6 and frac > 0) then
print(line);
end if;
end sub;
 
# Open "data.txt" and scan each line
var quakes: FCB;
if FCBOpenIn(&quakes, "data.txt") != 0 then
print("Error!\n");
ExitWithError();
end if;
 
ForEachLine(&quakes, PrintIfGt6); </syntaxhighlight>
 
{{out}}
<pre>$ cat data.txt
8/27/1883 Krakatoa 8.8
5/18/1980 MountStHelens 7.6
3/13/2009 CostaRica 5.1
1/23/4567 EdgeCase1 6
1/24/4567 EdgeCase2 6.0
1/25/4567 EdgeCase3 6.1
$ ./quakes.386
8/27/1883 Krakatoa 8.8
5/18/1980 MountStHelens 7.6
1/25/4567 EdgeCase3 6.1</pre>
 
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|Controls,SysUtils,Classes,StdCtrls,ExtCtrls}}
This code takes advantage of the standard Delphi "TStringGrid" object to do most of the heavy lifting. It is initially used to read the earthquake file into memory, breaking it up into of individual lines as it goes. Then the individual fields are stored in structurs/records attached to the data. finally, the data is sorted by magnitude so the earthquakes of magnitudes greater than six can be extracted. Because the data is now neatly organized in memory, all kinds of other process could be done, including sorting it by date or location. To make the problem more realistic, I extracted actual earthquake data from the first few months of 2023. I've post the data for other people to test here: [https://fountainware.com/download/EarthQuakes.txt EarthQuakes.txt]
 
<syntaxhighlight lang="Delphi">
Line 1,286 ⟶ 1,382:
13/04/2023 Canada_British_Columbia 6.00
</pre>
 
 
=={{header|Cowgol}}==
<syntaxhighlight lang="cowgol">include "cowgol.coh";
include "file.coh";
 
# Process a file line by line
interface LineCb(line: [uint8]);
sub ForEachLine(fcb: [FCB], cb: LineCb) is
var buf: uint8[256];
var ptr := &buf[0];
var length := FCBExt(fcb);
while length != 0 loop
var ch := FCBGetChar(fcb);
[ptr] := ch;
ptr := @next ptr;
if ch == '\n' then
[ptr] := 0;
ptr := &buf[0];
cb(&buf[0]);
end if;
length := length - 1;
end loop;
end sub;
 
# Get magnitude from line
# Cowgol does not support floating point arithmetic, so the integer and
# fractional parts are returned separately
sub magnitude(line: [uint8]): (i: uint8, frac: uint8) is
i := 0;
frac := 0;
var col: uint8 := 1;
var space: uint8 := 0;
# scan ahead to 3rd column
while col < 3 loop
var ch := [line];
line := @next line;
if ch == 0 then break; end if;
if ch <= ' ' then
while ch <= ' ' and ch != 0 loop
ch := [line];
line := @next line;
end loop;
col := col + 1;
end if;
end loop;
if ch == 0 then
return; # no 3rd column
end if;
line := @prev line;
var n: int32;
var pos: [uint8];
# grab integer part
(n, pos) := AToI(line);
if pos == line then
return; # no value
end if;
i := n as uint8;
if [pos] == '.' then
# grab fractional part
(n, pos) := AToI(@next pos);
frac := n as uint8;
end if;
end sub;
 
# Print any line that has a magnitude > 6
sub PrintIfGt6 implements LineCb is
var i: uint8;
var frac: uint8;
(i, frac) := magnitude(line);
if i > 6 or (i == 6 and frac > 0) then
print(line);
end if;
end sub;
 
# Open "data.txt" and scan each line
var quakes: FCB;
if FCBOpenIn(&quakes, "data.txt") != 0 then
print("Error!\n");
ExitWithError();
end if;
 
ForEachLine(&quakes, PrintIfGt6); </syntaxhighlight>
 
{{out}}
<pre>$ cat data.txt
8/27/1883 Krakatoa 8.8
5/18/1980 MountStHelens 7.6
3/13/2009 CostaRica 5.1
1/23/4567 EdgeCase1 6
1/24/4567 EdgeCase2 6.0
1/25/4567 EdgeCase3 6.1
$ ./quakes.386
8/27/1883 Krakatoa 8.8
5/18/1980 MountStHelens 7.6
1/25/4567 EdgeCase3 6.1</pre>
 
=={{header|D}}==
Line 2,342 ⟶ 2,340:
=={{header|Wren}}==
{{libheader|Wren-pattern}}
<syntaxhighlight lang="ecmascriptwren">import "io" for File
import "os" for Process
import "./pattern" for Pattern
 
var args = Process.arguments
9,485

edits