Google Interview Question
Developer Program EngineersCountry: United States
This is my code. I have a feeling I'm missing something here, coz this is pure programming logic. Nothing specific to Perl.
use strict;
my $LIMIT = 9;
my $file_name = "abc.txt";
open(FILE,"<$file_name");
my @lines = <FILE>;
my @new_lines = ();
my $new_ind = 0;
foreach my $line (@lines) {
if( length($line) > $LIMIT ) {
# Split it
my @words = split(" ",$line);
my $frame = "";
my $count = 0;
foreach my $word ( @words ) {
$count += (length($word));
if( $count > $LIMIT ) {
$new_lines[$new_ind] = $frame . "/\n";
$new_ind++;
$frame = "";
$count= (length($word) + 1);
}
$frame .= ($word . " ");
} # end foreach my $word
$new_lines[$new_ind] = $frame . "\n";
} else {
# Add it to new array
$new_lines[$new_ind] = $line;
}
$new_ind++;
} # end foreach $lines
# Write new lines into the old file
close( FILE);
open(FILE,">xyz.txt");
print FILE @new_lines;
close(FILE);
print "\nDone";
#!/usr/bin/env python
import sys
# Input : A Perl program file
# We need to modify the file to have a max of 80 characters per line and create
# a new perl file. Problem is we need to use "/" wherever we split the line
# and also, the split MUST happen at a place with white space.
def split_line(line, MAX_LIMIT=5):
"""
split a line, splitter is "/"
>>> list(split_line("ABCD EF", 5))
['ABCD/', 'EF']
# this one can't be split!
>>> list(split_line("ABCDEF", 5))
['ABCDEF']
>>> list(split_line("123456789 xyz", 10))
['123456789/', 'xyz']
"""
while len(line) > MAX_LIMIT:
# split line into words
words = line.split(" ")
count = 0
index = 0
# find the maximum "index" we can afford
for i in range(0, len(words)):
count = count + len(words[i]) + 1
if count >= MAX_LIMIT:
break
index = index + 1
# combines words upto "index" back
newline = " ".join(words[:index + 1])
# find the leftover line
left = words[index + 1:]
line = " ".join(left)
# is this the last chunk for this line?
if left:
yield newline + '/'
else:
yield newline
if line: # stop returning empty string
yield line
if __name__ == "__main__":
for line in sys.stdin:
line = line.rstrip()
for l in split_line(line):
print l
use strict;
use warnings;
my $limit = 80;
my $NF;
open($NF, ">limit_op.txt");
while (<>) {
my $line = $_;
do {
if ($line =~ /^(.{0,$limit})(?:(\s+)(.*)$|$)/) {
print $NF $1;
$line = $3;
print $NF "/\n$2" if(length($line) > 0);
}
} while (length($line) > 0);
print $NF "\n";
}
close($NF);
As simple python logic is as follows :
>>> line = "ABCDEF XYZ";
>>> LIMIT = 5
>>> newLines = ""
>>> while(len(line) > LIMIT) :
... index = line.rfind(' ', 0, LIMIT)
... if index == -1:
... index = line.find(' ', LIMIT)
... if index == -1:
... newLines = newLines + line
... line = ''
... else :
... newLines = newLines + line[0:index] + '/\n'
... line = line[index:]
...
>>> newLines = newLines + line
>>> print newLines
ABCDEF/
XYZ
in case you want to remove the whitespace while splitting you need to change the to the below line in the code :
line = line[index:] becomes line = line[index+1:]
A solution in Python
f = open('file.pl', 'r')
f2 = open('file2.pl', 'w')
lines = f.readlines();
for line in lines:
if len(line) > 80:
words = line.split()
line_len = 0
for word in words:
line_len += len(word)+1 # Plus 1 because of the whitespace
if line_len > 80:
f2.write('/\n')
line_len = 0
f2.write(word + ' ')
else:
f2.write(line.strip()) # Strip to remove the \n
f2.write('\n') # New line for all the lines. If a line is more than 80 chars, when we split it the remaining characters will be in their own line
#!/usr/bin/perl -w
open(SRCFILE,'src.txt');
open(DESTFILE,'>dest.txt');
#a sub to do the formating if number of characters is greater than xx
sub formatLine{
@words = split(' ',$_);
foreach $word(@words){
$len += length($word)+1;
if($len > 80){
print DESTFILE "\n";
$len = 0;
}
print DESTFILE $word," ";
}
print DESTFILE "\n";
}
while(<SRCFILE>){
chomp;
if(length($_) < 80){
print DESTFILE $_."\n";
}
else{
formatLine($_);
}
}
close(SRCFILE);
close(DESTFILE);
A perfectly working one...modified my previous post
#!/usr/bin/perl -w
open(SRCFILE,'src.txt');
open(DESTFILE,'>dest.txt');
#a sub to do the formating if number of characters is greater than xx
sub formatLine{
$len = 0;
@words = split(' ',$_);
foreach $word(@words){
$len += length($word)+1;
if($len > 80){
print DESTFILE "\n";
$len = length($word)+1;
}
print DESTFILE $word," ";
}
print DESTFILE "\n";
}
while(<SRCFILE>){
chomp;
if(length($_) < 80){
print DESTFILE $_."\n";
}
else{
formatLine($_);
}
}
close(SRCFILE);
close(DESTFILE);
#!/usr/bin/perl
use warnings;
my $MAXLINELENGTH = 50;
open FD, 'input.txt';
while (<FD>) {
chomp(my @line = split '', $_);
my $lineLenght = @line;
#print "$lineLenght\n";
if ($lineLenght > $MAXLINELENGTH ) {
my $numlines = $lineLenght / $MAXLINELENGTH;
#print "<$numlines><$lineLenght><$MAXLINELENGTH>\n";
my $line = 1;
for (my $count = 0; $count <= $numlines; $count++) {
my $startPos = $MAXLINELENGTH * $count;
my $endPos = $MAXLINELENGTH * $line - 1;
my $printline = join('', @line[$startPos..$endPos]);
my $delimiter = $line <= $numlines ? '\\' : "";
print "$printline $delimiter\n";
$line++;
}
}
}
The Simplest Possible Correct Perl Solution for the given problem.
#!/usr/bin/perl -w
open(SRCFILE,'/home/oracle/script/data_file/pp1_input.txt');
while(<SRCFILE>) {
chomp($_);
$line.=$_;
}
$ll = length($line);
print "$ll\n";
$i=0;
while($i < $ll) {
$NL = substr $line, $i, 80;
$NL.=" /";
push @NL, $NL;
$i = $i + 80;
}
foreach (@NL) {
print "$_\n";
}
My solution in perl using recursion
use warnings;
use strict;
open(FH, "infile.txt");
open(FH2, " > outfile.txt");
my @array=<FH>;
foreach (@array) {
process($_);
}
sub process {
my $line=shift;
my @tmp;
my $i=0;
$line=~s/([\d\w\W])/$tmp[$i]=$1;$i++;$1;/ge;##Get every word number symbol and space
if(scalar(@tmp)>80) {
my $count=80;
while($tmp[$count] ne " ") {
$count--;
}
if($count==80) {
$count=$count-2; ##Take care of "/" and white space
}
for(my $j=0;$j<$count;$j++) {
print FH2 $tmp[$j];
}
print FH2 "\/";
print FH2 "\n";
my $rem="";
for (my $j=$count+1;$j<scalar(@tmp);$j++) {
$rem.=$tmp[$j];
}
$i=0;
@tmp="";
process($rem);
}
else {
print FH2 @tmp;
}
}
you can also use range operators to solve this problem
my $read = "a.txt";
my $write = "a_modified.txt";
open(READ,"<$read");
open(WRITE,">$write");
while(<READ>) {
chomp $_;
my @arr = split(//,$_);
if (scalar(@arr)>= 80) {
print WRITE @arr[0 ..79],"\\"."\n";
print WRITE @arr[80 .. $#arr],"\n";
} else {
print WRITE "$_\n";
}
}
close READ;
close WRITE;
you can also use range operators to solve this problem
my $read = "a.txt";
my $write = "a_modified.txt";
open(READ,"<$read");
open(WRITE,">$write");
while(<READ>) {
chomp $_;
my @arr = split(//,$_);
if (scalar(@arr)>= 80) {
print WRITE @arr[0 ..79],"\\"."\n";
print WRITE @arr[80 .. $#arr],"\n";
} else {
print WRITE "$_\n";
}
}
close READ;
close WRITE;
Code in Python:
def main():
temp = ''
count = 0
with open ('story.txt','r') as f:
for line in f.readlines():
for char in line:
if char != ' ':
temp = temp + char
count += 1
else:
count += 1
if count < 80 :
with open('new_story.txt','a') as fh:
fh.write(temp + ' ')
temp = ''
else:
with open('new_story.txt','a') as fh:
fh.write('/' + '\n' + temp + ' ')
count = len(temp) + 1
temp = ''
if __name__ == "__main__":
main()
Algorithm can be following:
1. Read a file line by line & repeat step 2 - 7
2. Get the length of the line
3. If it is greater than 80 then split the line by white space & create array of words
4. Get the last element of the array
5. Write the array from 0 to (length - 1) including white space after every word
6. Write the "/" at the end
7. Write the last word of the array in the new line
What if there are multiple words- how will writing a last word help
- Anonymous September 25, 2013