I have the following function which takes a number as a parameter and should return a string.
fun n = unwords [foldl (\acc x -> acc ++ (unwords[show x] ++ " ")) "" [1..nr] ++ "\n"| nr <- [n, n - 1..0]]
The returned value for 5 is:
fun 5
"1 2 3 4 5 \n 1 2 3 4 \n 1 2 3 \n 1 2 \n 1 \n \n"
and
putStrLn $ fun 5
1 2 3 4 5
1 2 3 4
1 2 3
1 2
1
My question is where does the blank space from the start of the lines appear from? My expected result for the function is
fun 5
"1 2 3 4 5 \n1 2 3 4 \n1 2 3\n 1 2\n 1\n\n
The space comes from the outermost use of unwords, whose documentation states:
It joins words with separating spaces.
If you changed that unwords to concat, you would remove the spaces after newlines.
Related
n = 10
while n > 0:
print(n)
n=n-1
so far i have this which gives me
10
9
8 7 6 5 4321
but I want 10 9 8 7 6 5 4 3 2 1
You should use the 'end' parameter of print. By default, end="\n" in print, a newline character
n = 10
while n > 0:
print(n, end=" ")
n=n-1
There are several ways you could do that.
Firstly, and probably the simplest, you can use the end argument of print().
For instance, you could do something like this:
n = 10
while n > 0:
print(n, end=" ") # note the 'end' argument
n=n-1
Which gives : 10 9 8 7 6 5 4 3 2 1 (with a trailing space and without carriage return).
Another way I can think of, but involves a bit more complexity in my opinion, is using join().
Example:
print(" ".join(str(i) for i in range(10, 0, -1)))
Which gives : 10 9 8 7 6 5 4 3 2 1 (with a carriage return and without trailing space).
Consider:
|: 2 3 $ 1 2 3
1 1
2 2
3 3
|: 1 2 3
1 2 3
The first one makes sense to me: the rows are now columns. But, by analogy, I expected the output of the 2nd one to be:
|: 1 2 3
1
2
3
Why is it still a row, rather than a column?
|:
reverses the order of the axes of its argument
So
$ |: 2 3 $ 1 2 3
3 2
$ |: 1 2 3 $ 1 2 3
3 2 1
and naturally
$ |: 1 2 3
3
which is the list 1 2 3
The result that you expected has axes 3 1; you would get this for the transpose of the list 1 3 $ 1 2 3
] l =: 1 3 $ 1 2 3
1 2 3
|: l
1
2
3
($ l);($ |: l)
┌───┬───┐
│1 3│3 1│
└───┴───┘
Is it possible to align the spaces and characters of two strings perfectly?
I have two functions, resulting in two strings.
One just adds a " " between a list of digits:
digits = 34567
new_digits = 3 4 5 6 7
The second function takes the string and prints out the index of the string, such that:
digits = 34567
index_of_digits = 1 2 3 4 5
Now the issue that I am having is when the length of the string is greater than 10, the alignment is off:
I am supposed to get something like this:
Please advice.
If your digits are in a list, you can use format to space them uniformly:
L = [3,4,2,5,6,3,6,2,5,1,4,1]
print(''.join([format(n,'3') for n in range(1,len(L)+1)]))
print(''.join([format(n,'3') for n in L]))
Or with f-string formatting (Python 3.6+):
L = [3,4,2,5,6,3,6,2,5,1,4,1]
print(''.join([f'{n+1:3}' for n in range(len(L))]))
print(''.join([f'{n:3}' for n in L]))
Output:
1 2 3 4 5 6 7 8 9 10 11 12
3 4 2 5 6 3 6 2 5 1 4 1
Ref: join, format, range, list comprehensions
I'm trying to implement A006751 in J. It's pretty easy to do in Haskell, something like:
concat . map (\g -> concat [show $ length g, [g !! 0]]) . group . show
(Obviously that's not complete, but it's the basic heart of it. I spent about 10 seconds on that, so treat it accordingly.) I can implement any of this fairly easily in J, but the part that eludes me is a good, idiomatic J algorithm that corresponds to Haskell's group function. I can write a clumsy one, but it doesn't feel like good J.
Can anyone implement Haskell's group in good J?
Groups are usually done with the /. adverb.
1 1 2 1 </. 'abcd'
┌───┬─┐
│abd│c│
└───┴─┘
As you can see, it's not sequential. Just make your key sequential like so (essentially determining if an item is different from the next, and do a running sum of the resulting 0's and 1's):
neq =. 13 : '0, (}. y) ~: (}: y)'
seqkey =. 13 : '+/\neq y'
(seqkey 1 1 2 1) </. 'abcd'
┌──┬─┬─┐
│ab│c│d│
└──┴─┴─┘
What I need then is a function which counts the items (#), and tells me what they are ({. to just pick the first). I got some inspiration from nubcount:
diffseqcount =. 13 : ',(seqkey y) (#,{.)/. y'
diffseqcount 2
1 2
diffseqcount 1 2
1 1 1 2
diffseqcount 1 1 1 2
3 1 1 2
If you want the nth result, just use power:
diffseqcount(^:10) 2 NB. 10th result
1 3 2 1 1 3 2 1 3 2 2 1 1 3 3 1 1 2 1 3 2 1 2 3 2 2 2 1 1 2
I agree that /. ( Key ) is the best general method for applying verbs to groups in J. An alternative in this case, where we need to group consecutive numbers that are the same, is dyadic ;. (Cut):
1 1 0 0 1 0 1 <(;.1) 3 1 1 1 2 2 3
┌─┬─────┬───┬─┐
│3│1 1 1│2 2│3│
└─┴─────┴───┴─┘
We can form the frets to use as the left argument as follows:
1 , 2 ~:/\ 3 1 1 1 2 2 3 NB. inserts ~: in the running sets of 2 numbers
1 1 0 0 1 0 1
Putting the two together:
(] <;.1~ 1 , 2 ~:/\ ]) 3 1 1 1 2 2 3
┌─┬─────┬───┬─┐
│3│1 1 1│2 2│3│
└─┴─────┴───┴─┘
Using the same mechanism as suggested previously:
,#(] (# , {.);.1~ 1 , 2 ~:/\ ]) 3 1 1 1 2 2 3
1 3 3 1 2 2 1 3
If you are looking for a nice J implementation of the look-and-say sequence then I'd suggest the one on Rosetta Code:
las=: ,#((# , {.);.1~ 1 , 2 ~:/\ ])&.(10x&#.inv)#]^:(1+i.#[)
5 las 1 NB. left arg is sequence length, right arg is starting number
11 21 1211 111221 312211
main = do
file_name <- getLine
text <- readFile file_name
let b = prepare $ line text
let x = sth b
mapM_ (putStr . print_matrix . fst ) x
When I ran this code I got:
1 2 3
4 5 6
7 8 9
9 2 1
1 1 1
1 1 1
But in random lines I got extra newlines. When I wrote 300 lines I got 2 extra random newlines.
9 2 1
(extra enter)
1 1 1
1 1 1
I'm pretty sure putStr is printing the newlines read in from the file, unless prepare or sth is chopping them off.