mersenneforum.org

mersenneforum.org (https://www.mersenneforum.org/index.php)
-   jvang (https://www.mersenneforum.org/forumdisplay.php?f=153)
-   -   ¿Learning how to learn… (https://www.mersenneforum.org/showthread.php?t=23429)

xilman 2018-09-08 11:19

[QUOTE=jvang;495599]What do they mean by a "raw" partition? Is that unformatted, inaccessible to the system, or something else?[/QUOTE]A raw partition is an area of the disk. It contains information, including all the files, directories, free space, etc, as well as formatting information which tells the disk read/write heads where the former can be found. It is accessible to the system, usually under a name such as /dev/sda1, but the information requires a great deal of interpretation before it becomes useful to the vast majority of software. The process of "mounting" a partition puts that interpretation software in place so that what everything using a mounted partition sees files, directories, access times, read/write permissions and all the other complicated paraphrenalia.

jvang 2018-09-10 00:01

Thanks for the replies; I've been reading up on file systems in general to get more familiar with the fundamental ideas behind them. "Mounting" makes a bit more sense, but I still have a bit to figure out (some permissions stuff and where stuff ends up being mounted in particular).

[URL="https://www.codewars.com/kata/make-the-deadfish-swim/"]Make the Deadfish swim.[/URL] is giving me trouble. I know that in a non-functional language you could just have a parameter (which would always start at zero) that changes based on inputs and outputs whenever asked to, but I don't think that's an option in Haskell.

I was thinking I could use splitAt or something to make lists of strings that all end in [C]'o'[/C], then execute the commands starting from zero and output the resultant list. However, for each output after the second I need to reuse the outputs from before, and I don't know how to do that.

I might have a bad understanding of the differences between functional and non-functional languages, but I think the way I'm trying this kata is not a functional way :ermm: (I hope that I don't need monads; they're scary!)

Nick 2018-09-10 08:13

[QUOTE=jvang;495790][URL="https://www.codewars.com/kata/make-the-deadfish-swim/"]Make the Deadfish swim.[/URL] is giving me trouble...I think the way I'm trying this kata is not a functional way :ermm: (I hope that I don't need monads; they're scary!)[/QUOTE]
No, you don't need monads here!

This is one way to set it up in Haskell: write a recursive function
[CODE]mds :: Int -> String -> [Int][/CODE]taking as inputs the current value of the integer and the remaining characters to process in the string,
and returning as output the list of integers generated if you start with that value and apply the instructions in that string.
Then write a second function making the initial call:
[CODE]mdss :: String -> [Int]
mdss s = mds 0 s
[/CODE]

jvang 2018-09-11 00:27

[QUOTE=Nick;495821]No, you don't need monads here!

This is one way to set it up in Haskell: write a recursive function
[CODE]mds :: Int -> String -> [Int][/CODE]taking as inputs the current value of the integer and the remaining characters to process in the string,
and returning as output the list of integers generated if you start with that value and apply the instructions in that string.
Then write a second function making the initial call:
[CODE]mdss :: String -> [Int]
mdss s = mds 0 s
[/CODE][/QUOTE]

That's a neat way of doing this; thanks!

Here is my elegant code resulting from that recursion... :ermm:

[CODE]module Kata.Deadfish (parse) where
import Data.List
parse :: String -> [Int]
parse x = map (parsing 0) (subs x)
parsing a (x:xs) = if x == 'i' then parsing (a + 1) xs else if x == 'd' then parsing (a - 1) xs else if x == 's' then parsing (a ^ 2) xs else if x == 'o' then a else parsing a xs
subs x = [(filter (/='o') q) ++ "oo" | q <- (nub $ filter ((=='o') . last) (tail $ inits x))][/CODE]

I was thinking about trying some guards to pattern match instead of weird if statements, but they looked weird and didn't work too smoothly :whee:

I'm actually surprised at how little refactoring I needed to make the code work. I code with the convoluted if statements a lot, so it's easy for me to follow what happens when code runs through it. That really makes fixing errors a piece of cake!

jvang 2018-09-11 23:58

I read some more on commands that have to do with [C]/etc/fstab[/C], and [C]swapon[/C]/[C]swapoff[/C] looked important.

Edit: In the process of looking through Ubuntu's online manpages, I found a neat guide to the number at the end of the title of a manpage.

[QUOTE](1) - Executable programs or shell commands
(2) - System calls (functions provided by the kernel)
(3) - Library calls (functions within program libraries)
(4) - Special files (usually found in /dev)
(5) - File formats and conventions, e.g. /etc/passwd
(6) - Games
(7) - Miscellaneous (including macro packages and conventions)
(8) - System administration commands (usually only for root)[/QUOTE]
[C]swapon[/C] is used to specify devices on which paging and swapping are to take place. Using [C]-a[/C] as a parameter makes all devices specially marked (with ``swap''?) in [C]/etc/fstab[/C] available for swap use, skipping over those that are already in use. Alternatively, you can specify a particular device/file with its UUID or label (not sure what a label is...).

These same parameters apply for [C]swapoff[/C] too, which disables swap use. There are many other parameters for each, but the only one that seems like it would be frequently useful is [C]-p[/C], with which you specify the priority of the swap device. I think I get the concept of priority, but why are there [$]2^{15}[/$] levels of priority? Niceness for [C]top[/C] has a similar incremental system with far fewer (or far less/lesser?) options, but there are so many for swap priority! :jvang:

Additionally, the manpage mentions that one should not use [C]swapon[/C] on a file with "holes". I looked it up, but it seemed pretty weird. The best analogy that I could find was:

[QUOTE]Suppose you've used up the 20Gigs of the VM's disk space and you decide to delete some data. Without sparse file support, in-spite of the deletion, the 20Gigs still remain occupied in the underlying physical hard disk. But if the filesystem supports holes, then the VM can 'punch' a hole corresponding to the files deleted, thereby freeing up physical disk space.[/QUOTE]
This was referring to virtual machines, which may of may not be what the manpage was referring to. Is there a better explanation of whatever this is?

Nick 2018-09-12 09:03

The interesting part of swapping/paging is this:
when the computer has to copy bytes from memory to disk in order to free up space, which bytes should it choose?
And when it has to copy them back from the disk into memory so that they can be accessed by a running process, how does it decide what to overwrite?
Various page replacement algorithms get used (you can find a comparison of them in Andy Tanenbaum's "Modern Operating Systems" book).

For holes: on Linux/Unix systems, you can take the kernel's pointer to your current position in an open file and move it beyond the current end of file (try "man 2 lseek").
Intervening blocks are not allocated until someone actually writes to them.

jvang 2018-09-13 00:54

[QUOTE=Nick;495934]The interesting part of swapping/paging is this:
when the computer has to copy bytes from memory to disk in order to free up space, which bytes should it choose?
And when it has to copy them back from the disk into memory so that they can be accessed by a running process, how does it decide what to overwrite?
Various page replacement algorithms get used (you can find a comparison of them in Andy Tanenbaum's "Modern Operating Systems" book).[/QUOTE]

I'd guess that each process has a swap priority assigned to them, with less important applications being copied in first. Essential system processes would be the last, and thus should be able to avoid being swapped at all.

[QUOTE]For holes: on Linux/Unix systems, you can take the kernel's pointer to your current position in an open file and move it beyond the current end of file (try "man 2 lseek").
Intervening blocks are not allocated until someone actually writes to them.[/QUOTE]

How would you write to the blocks after skipping them? And why would you want to do that in the first place?

There's a lot of stuff in [C]/etc[/C], and all of which seems to be configuration files for applications and shell commands/scripts. I see the [C]cron[/C] files, [C]logrotate[/C] stuff, and app-specific config files among other things. Is there anything here that isn't a configuration file, or is that the purpose of [C]/etc[/C]?

Working on a new kata, [URL="https://www.codewars.com/kata/valid-parentheses/"]Valid Parentheses[/URL]. I figured I'd attempt a similar approach to the Deadfish parser, using an accumulator and recursion:

[CODE]validParentheses :: String -> Bool
validParentheses x = if check 0 x < 1 then True else if check 0 x == False then False else True
check a (x:xs) = if a >= 0 then if x == '(' then check (a + 1) xs else if x == ')' then check (a - 1) xs else False else False[/CODE]

I have 2 problems so far;

A) [C]if check 0 x < 1[/C] brings up a [C]No instance for (Num Bool)[/C], which I get more often than I think I should. What's up with being unable to use numeric values with the comparators?

B) The check function also won't run, with a [C]Non-exhaustive patterns[/C] error. I'm pretty sure that means it has no base case and will run infinitely, but I'm pretty sure it works logically. I've followed what should occur as a simple string of parentheses passes through, but only strings with more than 2 or 3 invalid parentheses run without error. Weird! :max:

More off-topic than usual: I was reading around the Internet and the forum, and came across something about "New Math" and Common Core. After looking up New Math I'm now wondering how math used to be taught, and why we made the change. I tried reading up on it but there's a bunch of crap on Common Core and it seems to be more politics than math :unsure:

Nick 2018-09-13 07:51

[QUOTE=jvang;495978]I'd guess that each process has a swap priority assigned to them, with less important applications being copied in first. Essential system processes would be the last, and thus should be able to avoid being swapped at all.
[/QUOTE]
Modern operating systems don't swap entire processes in and out any more but can move parts of their address space in and out instead (pages).
Different processes may be running the same program (e.g. if you open several windows running a copy of the shell), in which case they can share the part of their memory containing the code.
Processes can have several threads, sharing both code and global data as well but each with their own stack, etc.
This all makes modern computers more efficient - and more complex!
[QUOTE=jvang;495978]
How would you write to the blocks after skipping them? And why would you want to do that in the first place?
[/QUOTE]
Suppose you want to store a list of a couple of thousand 8-digit numbers in a file.
One way is to write a '1' at the offset given by each number, leaving a '0' everywhere else.
Looking up whether a particular number occurs in the list is then a fast operation.
On operating systems which do not support holes, however, the file would be 100MB long even though most of it is empty.
On Linux/Unix systems, stretches of the file consisting entirely of zeroes get omitted, saving a lot of space.
[QUOTE=jvang;495978]
There's a lot of stuff in [C]/etc[/C], and all of which seems to be configuration files for applications and shell commands/scripts. I see the [C]cron[/C] files, [C]logrotate[/C] stuff, and app-specific config files among other things. Is there anything here that isn't a configuration file, or is that the purpose of [C]/etc[/C]?
[/QUOTE]
Yes, absolutely right - that's what it's for!
[QUOTE=jvang;495978]
Working on a new kata, [URL="https://www.codewars.com/kata/valid-parentheses/"]Valid Parentheses[/URL]. I figured I'd attempt a similar approach to the Deadfish parser, using an accumulator and recursion:

[CODE]validParentheses :: String -> Bool
validParentheses x = if check 0 x < 1 then True else if check 0 x == False then False else True
check a (x:xs) = if a >= 0 then if x == '(' then check (a + 1) xs else if x == ')' then check (a - 1) xs else False else False[/CODE]I have 2 problems so far;

A) [C]if check 0 x < 1[/C] brings up a [C]No instance for (Num Bool)[/C], which I get more often than I think I should. What's up with being unable to use numeric values with the comparators?

B) The check function also won't run, with a [C]Non-exhaustive patterns[/C] error. I'm pretty sure that means it has no base case and will run infinitely, but I'm pretty sure it works logically. I've followed what should occur as a simple string of parentheses passes through, but only strings with more than 2 or 3 invalid parentheses run without error. Weird! :max:
[/QUOTE]
A) Your check function returns False but validParentheses then asks if this is less than 1!
B) Your check function calls itself with a shorter string which may now be empty, but the pattern "check a (x:xs)" only matches non-empty strings.
[QUOTE=jvang;495978]
More off-topic than usual: I was reading around the Internet and the forum, and came across something about "New Math" and Common Core. After looking up New Math I'm now wondering how math used to be taught, and why we made the change. I tried reading up on it but there's a bunch of crap on Common Core and it seems to be more politics than math :unsure:[/QUOTE]
Absolutely right again!

jvang 2018-09-14 00:01

Thanks for clarifying what was up with my code!

[CODE]module Codewars.Parentheses where

validParentheses :: String -> Bool
validParentheses x = if check 0 x == 0 then True else False
check a [] = 0
check a [x] = if a >= 0 then if x == '(' then a + 1 else if x == ')' then a - 1 else (-1) else (-1)
check a (x:xs) = if a >= 0 then if x == '(' then check (a + 1) xs else if x == ')' then check (a - 1) xs else (-1) else (-1)[/CODE]

Works nicely, and gave me way fewer errors upon the big edits :whee:

I wasn't sure what to read about for Linux today so I read the [C]man[/C] manpage. It looks like there are about 50 options for it! :unsure:

Some things I learned:

[C]man[/C] searches the sections of the system manual in this weird order, bringing up the first one with a match:

[C]1 n l 8 3 2 3posix 3pm 3perl 5 4 9 6 7[/C] (each section delimited with spaces)

You can change the order in [C]/etc/manpath.config[/C], unsurprisingly.

The manpage covers the usage of [C]man[/C] in extraordinary depth, and over two-thirds of it are a general overview of what it is meant to do, its configuration options/other utilities, and the usage of its many command line options. There's a big section labeled "ENVIRONMENT," but I'm not sure what all of that is.

In my little Coding Fundamentals course (which is looking more like history of computers or something) I actually learned some little tidbits; the first transistor was invented in ~1947, and the first microprocessor (released in the early 1970s by IBM) had 2300 transistors. Compare that just to today's smartphones; the A11 chip in an iPhone 8 has 4.3 billion transistors on a die just 87.66 mm² in size! I'm not sure which is more impressive, fitting that many transistors on/in that chip or managing all of that heat without letting anything overheat...

Someone told me that the coding class was very difficult, but we haven't even covered what coding is, or even mentioned it apart from the name of the class :ermm:

jvang 2018-09-15 03:09

[QUOTE=jvang;495176]My dad has never learned elementary math, since he missed several years of the fundamentals. He's taking the Prealgebra course from Art of Problem Solving, and is having a blast with it....[/QUOTE]

Here's a problem from last week that he was working on:

[QUOTE]Genet multiplied a 3-digit number by 1002 and got AB007C, where A, B, and C stand for digits. What was Genet's original 3-digit number?[/QUOTE]

It was pretty easy to brute-force our way to the answer with some Haskell code, but I know that there is a more elegant, mathematical way to approach this (these are their writing problems, which ask for some sort of proof). A preceding problem to this was:

[QUOTE]If we multiply a two-digit number by 102, must the units digit of the product be twice the hundreds digit of the product? Why or why not?[/QUOTE]

I represented the number as AB, with each letter representing digits. Then I took out the A as A * 10, to keep its place. Going through the problem like this shows that the units digit must be twice the hundreds digit [I]if you do not carry the excess sums[/I], i.e. 5 + 5 = 10, you carry the 1 to the tens digit. I'm not sure if they meant for the digits to be carried over before comparing their values; the lesson involved learning about how to distribute products across sums, like (40 + 3)(30 + 8).

How would you work out these problems/proofs?

S485122 2018-09-15 08:24

The first number has three digits let's say a,b and c.
it is thus 100*a+10*b+1*c
Multiply it by 1002
you get :
100000*a+10000*b+1000*c+200*a+20*b+2*c
You know that that number is represented by :
100000*A+10000*B+1000*0+100*0+10*7+1*C
Having both representations of the number one above the other lets you draw some conclusions. (Especially since you already found the answer :-)

Jacob


All times are UTC. The time now is 21:53.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.