Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
P
p1
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Iterations
Wiki
Requirements
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Locked files
Build
Pipelines
Jobs
Pipeline schedules
Test cases
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Code review analytics
Issue analytics
Insights
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
CDIS
Computer Sciences
Courses
CS537
fall24
public
p1
Merge requests
!1
Replace letter-boxed.c
Code
Review changes
Check out branch
Download
Patches
Plain diff
Open
Replace letter-boxed.c
hpark383/p1:main
into
main
Overview
0
Commits
5
Pipelines
0
Changes
1
Open
Hye Won Park
requested to merge
hpark383/p1:main
into
main
6 months ago
Overview
0
Commits
5
Pipelines
0
Changes
1
Expand
0
0
Merge request reports
Compare
main
version 4
75f42a4c
6 months ago
version 3
8df3e8b8
6 months ago
version 2
7299d118
6 months ago
version 1
4772a884
6 months ago
main (HEAD)
and
version 2
latest version
43c1f0d8
5 commits,
6 months ago
version 4
75f42a4c
4 commits,
6 months ago
version 3
8df3e8b8
3 commits,
6 months ago
version 2
7299d118
2 commits,
6 months ago
version 1
4772a884
1 commit,
6 months ago
1 file
+
187
−
0
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
solution/letter-boxed.c
+
187
−
0
Options
#define _POSIX_C_SOURCE 200809L
#include
<stdbool.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<string.h>
#define MAX_SIDES 26
#define MAX_ALPHABET 10
#define INITIAL_DICT_SIZE 10000
#define MAX_WORD_SIZE 100
typedef
struct
{
char
sides
[
MAX_SIDES
][
MAX_ALPHABET
+
1
];
int
numSides
;
}
Board
;
void
loadBoard
(
const
char
*
fileName
,
Board
*
board
);
char
**
loadDict
(
const
char
*
fileName
,
int
*
num
);
int
isValidWord
(
const
char
*
inputWord
,
char
**
dict
,
Board
*
board
,
int
dictNum
,
int
*
trackChar
);
void
freeMemory
(
char
**
dict
,
int
dictNum
);
int
main
(
int
argc
,
char
*
argv
[])
{
if
(
argc
!=
3
)
{
printf
(
"Usage: ./letter-boxed <board file> <dictionary file>
\n
"
);
exit
(
1
);
}
Board
board
;
loadBoard
(
argv
[
1
],
&
board
);
// load letter boxed board with board file input
int
dictNum
=
0
;
// number of words in dictionary
char
**
dict
=
loadDict
(
argv
[
2
],
&
dictNum
);
// store dictionary words in 2d array
int
trackChar
[
26
]
=
{
0
};
// array to track characters in word
char
currInput
[
MAX_WORD_SIZE
];
char
prevInput
[
MAX_WORD_SIZE
]
=
""
;
while
(
scanf
(
"%s"
,
currInput
)
!=
EOF
)
{
if
(
prevInput
[
0
]
!=
'\0'
&&
prevInput
[
strlen
(
prevInput
)
-
1
]
!=
currInput
[
0
])
{
printf
(
"First letter of word does not match last letter of previous word
\n
"
);
exit
(
1
);
}
if
(
!
isValidWord
(
currInput
,
dict
,
&
board
,
dictNum
,
trackChar
))
{
freeMemory
(
dict
,
dictNum
);
exit
(
0
);
}
strcpy
(
prevInput
,
currInput
);
// update previous input
}
for
(
int
i
=
0
;
i
<
board
.
numSides
;
i
++
)
{
for
(
size_t
j
=
0
;
j
<
strlen
(
board
.
sides
[
i
]);
j
++
)
{
if
(
!
trackChar
[
board
.
sides
[
i
][
j
]
-
'a'
])
{
printf
(
"Not all letters used
\n
"
);
exit
(
0
);
}
}
}
printf
(
"Correct
\n
"
);
freeMemory
(
dict
,
dictNum
);
return
0
;
}
void
loadBoard
(
const
char
*
fileName
,
Board
*
board
)
{
FILE
*
file
=
fopen
(
fileName
,
"r"
);
if
(
!
file
)
{
printf
(
"Board file invalid
\n
"
);
exit
(
1
);
}
int
trackCharNum
[
26
]
=
{
0
};
board
->
numSides
=
0
;
// read each side(line) from file and store in the board side array
while
(
fgets
(
board
->
sides
[
board
->
numSides
],
MAX_ALPHABET
+
1
,
file
)
!=
NULL
)
{
board
->
sides
[
board
->
numSides
][
strcspn
(
board
->
sides
[
board
->
numSides
],
"
\n
"
)]
=
0
;
// remove newline
for
(
size_t
i
=
0
;
i
<
strlen
(
board
->
sides
[
board
->
numSides
]);
i
++
)
{
int
charIndex
=
board
->
sides
[
board
->
numSides
][
i
]
-
'a'
;
if
(
trackCharNum
[
charIndex
]
>
0
)
{
printf
(
"Invalid board
\n
"
);
// board contains a letter more than once
exit
(
1
);
}
trackCharNum
[
charIndex
]
++
;
}
board
->
numSides
++
;
// next side(line) of the board
}
if
(
board
->
numSides
<
3
)
{
printf
(
"Invalid board
\n
"
);
exit
(
1
);
}
fclose
(
file
);
}
char
**
loadDict
(
const
char
*
fileName
,
int
*
num
)
{
FILE
*
file
=
fopen
(
fileName
,
"r"
);
if
(
!
file
)
{
printf
(
"Dictionary file invalid
\n
"
);
exit
(
1
);
}
int
dictSize
=
INITIAL_DICT_SIZE
;
char
**
dict
=
malloc
(
dictSize
*
sizeof
(
char
*
));
if
(
!
dict
)
{
printf
(
"Memory allocation of dictionary array failed
\n
"
);
exit
(
1
);
}
char
word
[
MAX_WORD_SIZE
];
while
(
fscanf
(
file
,
"%s"
,
word
)
!=
EOF
)
{
if
(
*
num
>=
dictSize
)
{
dictSize
*=
2
;
char
**
newDict
=
realloc
(
dict
,
dictSize
*
sizeof
(
char
*
));
// dynamically allocate memory
if
(
!
newDict
)
{
freeMemory
(
dict
,
*
num
);
printf
(
"Memory allocation failed
\n
"
);
exit
(
1
);
}
dict
=
newDict
;
}
dict
[
*
num
]
=
strdup
(
word
);
// assign word in the dictionary file to the dictionary array
if
(
!
dict
[
*
num
])
{
freeMemory
(
dict
,
*
num
);
printf
(
"Memory allocation failed
\n
"
);
exit
(
1
);
}
(
*
num
)
++
;
// increment num after allocation
}
fclose
(
file
);
return
dict
;
}
int
isValidWord
(
const
char
*
inputWord
,
char
**
dict
,
Board
*
board
,
int
dictNum
,
int
*
trackChar
)
{
bool
foundDict
=
false
;
for
(
int
i
=
0
;
i
<
dictNum
;
i
++
)
{
if
(
strcmp
(
inputWord
,
dict
[
i
])
==
0
)
{
foundDict
=
true
;
break
;
}
}
if
(
!
foundDict
)
{
printf
(
"Word not found in dictionary
\n
"
);
return
0
;
}
int
prevSideNum
=
-
1
;
for
(
size_t
i
=
0
;
i
<
strlen
(
inputWord
);
i
++
)
{
char
currChar
=
inputWord
[
i
];
// loop through each character of word
bool
foundBoard
=
false
;
for
(
int
sideNum
=
0
;
sideNum
<
board
->
numSides
;
sideNum
++
)
{
if
(
strchr
(
board
->
sides
[
sideNum
],
currChar
)
!=
NULL
)
{
// returns the index of char if found in board side
foundBoard
=
true
;
if
(
prevSideNum
==
sideNum
)
{
printf
(
"Same-side letter used consecutively
\n
"
);
return
0
;
}
trackChar
[
currChar
-
'a'
]
=
1
;
prevSideNum
=
sideNum
;
// update previous side num to the board side num in which char exists
break
;
// break out of the loop since the char is found in the board
}
}
if
(
!
foundBoard
)
{
printf
(
"Used a letter not present on the board
\n
"
);
return
0
;
}
}
return
1
;
}
void
freeMemory
(
char
**
dict
,
int
dictNum
)
{
for
(
int
i
=
0
;
i
<
dictNum
;
i
++
)
{
free
(
dict
[
i
]);
}
free
(
dict
);
}
Loading