So I've been working on this problem of printing out a Sudoku board for the past couple hours and I'm almost finished but I'm stuck at the final step. So what I have is a Sudoku board represented as a "list of lists" (i.e. board = [[1, 3, 5, 7, 0, 2, 0, 0, 0], [3, 4, 5, ...], ...]
I've been able to print out a line with formatting with the following function:
line i s_board = intercalate " | " . map unwords . chunksOf 3 $ map show a
where
a = s_board!!i
So by making a call like "line 0 board" i would get "1 3 5 | 7 0 2 | 0 0 0" which is partially what I need. Next I tried to use a "do block" to output the board that I need which looked something like this:
print = do line 0 board
line 1 board
...
This wouldn't even compile, and when I did something like this:
print = do
line 0 board
line 1 board
The appropriate list was printed multiple times which is fairly confusing. I wanted to work my way up to including extra formatting such as printing a string such as "----------" after every three lines to complete the board but I can't even get the other thing to work right yet. I'd appreciate any help offered with these issues.
It would be easier and more elegant to produce a function that takes your
board, makes one big string, and finally prints it, rather than worrying about
printing every line via a do block.
So, if we simplify your line showing function to take one line of the board:
showLine :: [Int] -> String
showLine = intercalate " | "
. map unwords
. chunksOf 3
. map show
Then, we need to get the string representation of each line and put them all
together. This looks pretty much like the showLine code:
showBoard :: [[Int]] -> String
showBoard = intercalate "---------------------\n"
. map unlines
. chunksOf 3
. map showLine
Using the example board
-- Obviously not a valid sudoku board...
example :: [[Int]]
example = replicate 9 [ 1, 2, 3, 4, 5, 6, 7, 8, 9 ]
*Main> putStrLn $ showBoard example
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
---------------------
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
---------------------
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
1 2 3 | 4 5 6 | 7 8 9
Your original attempt didn't compile because it violates Haskell's layout rules.
The second didn't do what you expect because line n board is a list, so the do-notation means nondeterminism, not sequencing of IO actions. If you tried to put a type like
print :: IO ()
above your function (incidentally, print is defined in the Standard Prelude and you should be getting a warning about shadowing it), the type-checker would inform you of your mistake. If you really wanted to print out the board like this (although as the other answer suggests, building a string and then printing this whole thing out is much better), you could try
printBoard :: IO ()
printBoard = do print $ line 0 board
print $ line 1 board
or to print the whole board,
printBoard = mapM_ (print . showLine) board
where showLine is like your print but with the indexing stripped out.
Related
I have data in Stata regarding the feeling of the current situation. There are seven types of feeling. The data is stored in the following format (note that the data type is a string, and one person can respond to more than 1 answer)
feeling
4,7
1,3,4
2,5,6,7
1,2,3,4,5,6,7
Since the data is a string, I tried to separate it by
split feeling, parse (,)
and I got the result
feeling1
feeling2
feeling3
feeling4
feeling5
feeling6
feeling7
4
7
1
3
4
2
5
6
7
1
2
3
4
5
6
7
However, this is not the result I want. which is that the representative number of feelings should go into the correct variable. For instance.
feeling1
feeling2
feeling3
feeling4
feeling5
feeling6
feeling7
4
7
1
3
4
2
5
6
7
1
2
3
4
5
6
7
I am not sure if there is any built-in command or function for this kind of problem. I am thinking about using forval in looping through every value in each variable and try to juggle it around into the correct variable.
A loop over the distinct values would be enough here. I give your example in a form explained in the Stata tag wiki as more helpful and then give code to get the variables you want as numeric variables.
* Example generated by -dataex-. For more info, type help dataex
clear
input str13 feeling
"4,7"
"1,3,4"
"2,5,6,7"
"1,2,3,4,5,6,7"
end
forval j = 1/7 {
gen wanted`j' = `j' if strpos(feeling, "`j'")
gen better`j' = strpos(feeling, "`j'") > 0
}
l feeling wanted1-better3
+---------------------------------------------------------------------------+
| feeling wanted1 better1 wanted2 better2 wanted3 better3 |
|---------------------------------------------------------------------------|
1. | 4,7 . 0 . 0 . 0 |
2. | 1,3,4 1 1 . 0 3 1 |
3. | 2,5,6,7 . 0 2 1 . 0 |
4. | 1,2,3,4,5,6,7 1 1 2 1 3 1 |
+---------------------------------------------------------------------------+
If you wanted a string result that would be yielded by
gen wanted`j' = "`j'" if strpos(feeling, "`j'")
Had the number of feelings been 10 or more you would have needed more careful code as for example a search for "1" would find it within "10".
Indicator (some say dummy) variables with distinct values 1 or 0 are immensely more valuable for most analysis of this kind of data.
Note Stata-related sources such as
this FAQ
this paper
and this paper.
I must create a sequence of numbers using the number of elements that an list has.
arr1=(1 2 3 4 5 6)
I thought about the following expression in order to do so, but it is now working.
echo {0..$(expr ${#arr1[*]} - 1)}
{0..5} # output
The correct output should be:
0 1 2 3 4 5
Could anyone explain me why I do not get the correct values?
You just need to add an eval:
$ a=(1 2 3 4 5 6)
$ eval echo {0..$(expr ${#a[*]} - 1)}
0 1 2 3 4 5
I'm working on a machine translation project in which I have 4.5 million lines of text in two languages, English and German. I would like to shuffle these lines prior to dividing the data into shards on which I will train my model. I know the shuf command described here allows one to shuffle lines in one file, but how can I ensure that corresponding lines in the second file are also shuffled into the same order? Is there a command to shuffle lines in both files?
TL;DR
paste to create separate columns from two files into a single file
shuf on the single file
cut to split the columns
Paste
$ cat test.en
a b c
d e f
g h i
$ cat test.de
1 2 3
4 5 6
7 8 9
$ paste test.en test.de > test.en-de
$ cat test.en-de
a b c 1 2 3
d e f 4 5 6
g h i 7 8 9
Shuffle
$ shuf test.en-de > test.en-de.shuf
$ cat test.en-de.shuf
d e f 4 5 6
a b c 1 2 3
g h i 7 8 9
Cut
$ cut -f1 test.en-de.shuf> test.en-de.shuf.en
$ cut -f2 test.en-de.shuf> test.en-de.shuf.de
$ cat test.en-de.shuf.en
d e f
a b c
g h i
$ cat test.en-de.shuf.de
4 5 6
1 2 3
7 8 9
How would I go about making a function so that x has a range of values from x=0 to x=19 and if the x value exceeds 19 or is below zero how can I get it to wrap around
From:
x=20, x=21, x=22 and x=(-1), x=(-2), x=(-3)
To:
x=0, x=1, x=2 and x=19, x=18, x=17 respectively?
I've heard of modular arithmetic which is apparently the way I should deal with it.
Usually you would use the built-in functions mod and rem, but I assume they are off-limits for homework. So you can write your own function, e.g.
mod20 x | x < 0 = ...
| x > 19 = ...
| otherwise = x
There are different things you can try to fill in the ...s. One of the easiest is repeated addition or subtraction, but I don't want to spoil all the fun.
Once you have this function, you can "rescale" the values after every "normal" arithmetic operation, e.g. mod20 (12 + 17).
Try using the mod function:
(-5) `mod` 20 ==> 15
5 `mod` 20 ==> 5
20 `mod` 20 ==> 0
25 `mod` 20 ==> 5
See also wikipedia on the topic.
Use
x `mod` 20
(This is a filler to make the answer 30 characters.)
Since length is a generic method, why can't I do
length.character <- nchar
? It seems that strings are treated special in R. Is there a reason for that? Would you discourage defining functions like head.character and tail.character?
If you look at the help page for InternalMethods (mentioned in the details portion of the help page for length) it states that
For efficiency, internal dispatch only
occurs on objects, that
is those for which ‘is.object’ returns true.
Vectors are not objects in the same sense as other objects are, so the method dispatch is not being done on any basic vectors (not just character). if you really want to use this type of dispatch you need a defined object, e.g.:
> tmp <- state.name
> class(tmp) <- 'mynewclass'
> length.mynewclass <- nchar
> length(tmp)
[1] 7 6 7 8 10 8 11 8 7 7 6 5 8 7 4 6 8 9 5 8 13 8 9 11 8
[26] 7 8 6 13 10 10 8 14 12 4 8 6 12 12 14 12 9 5 4 7 8 10 13 9 7
>
My 2c:
Strings are not treated specially in R. If length did the same thing as nchar, then you would get unexpected results if you tried to compute length(c("foo", "bazz")). Or to put it another way, would you expect the length of a numeric vector to return the number of digits in each element of the vector or the length of the vector itself?
Also creating this method might side-effect other functions which expect the normal string behavior.
Now I found a reason not to define head.character: it changes the way how head works. For example:
head.character <- function(s,n) if(n<0) substr(s,1,nchar(s)+n) else substr(s,1,n)
test <- c("abc", "bcd", "cde")
head("abc", 2) # works fine
head(test,2)
Without the definition of head, the last line would return c("abc", "bcd"). Now, with head.character defined, this function is applied to each element of the list and returns c("ab", "bc", "cd").
But I have a strhead and a strtail function now.. :-)