2015年11月23日 星期一

Functors,applicatives,and monads notes(I)

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html
比from great of good更多的圖片說明,有舉其他語言的例子來解釋為什麼需要這些元素。

筆記
functor用來做條件選擇的function很酷!
有些function也能當作functor來用! (fmap (+3) (+2)) 帶出下一個applicative
前面提到functor感覺是把單純的value用context裝起來,context就是所謂的functor。如果context裡面裝的不是value而是function時,就變成applicative。

functor用來包value applicative用來包function來和funcotr對接,monad(>>=)用來把包好的value塞到function裡,他舉的half例子是吃一般value轉成包好的,如果一開始就傳包好的(如Just 4)該怎麼辦?monad就是拿來處理此狀況(?)
Maybe是三位一體阿! 符合上面三個「東西」的條件。
以(>>=)的datatype來看:(>>=) :: Monad m => m a -> (a -> m b) -> m b
他吃兩個東西:我們想算的,已經用m包好的數值a,原本只吃數值a,吐運算完用m包好的b的function。最後吐出算好用m包好的b。
順帶一提:>>=是中置運算。

IO居然也是monad!!!
getLine吃user輸入,包成IO String
readFile吃String,傳回文件內容(包成IO String)
putStrLn吃String,傳到螢幕上(IO ())
用>>=把大家串起來:getLine >>= readFile >>= putStrLn
可以輸入一段String(檔名),getLine把他包成IO String餵給readFile,readFile根據檔名把檔案內容抓出來包成IO String,最後給putStrLn輸出到螢幕上。 記住每個函數其實都是吃String,是我們用了>>=讓他們也可以接受IO (String)的格式。

有講一個do的文法糖,範例如下:
foo = do filename <- getLine contents <- readFile filename putStrLn contents
<-似乎在do block裡面有其效果?

看完才發現有中文版orz 不過是簡體字
還有Python版

待釐清:instance?
different between <$> and <*>:就是applicatives和functor的文法糖

小結:舉例詳盡的網站,但抽象的概念不可能用實際例子去完全窮舉,還是得從定義下手做苦工才行。


2015年7月23日 星期四

LeetCode:Single Number

題目:

Given an array of integers, every element appears twice except for one. Find that single one.

一串整數數列,找出只出現一次的數字。



想法:

XOR的經典題,還能應用在swap函數,不用額外儲存空間
C#:
  1. public void swap(int a , int b){
  2. a^=b;
  3. b^=a;
  4. a^=b;
  5. }
因為a^a=0 (a^b)^a=b的關係使然


Accepted Solution:


C#


  1. public class Solution {
  2. public int SingleNumber(int[] nums) {
  3. int ans = 0;
  4. foreach (int i in nums){
  5. ans^=i;
  6. }
  7. return ans;
  8. }
  9. }

2015年7月22日 星期三

20150722

今天都在解題目,感覺很容易在奇怪的地方卡關。
本日完成的題目有

Maximum Depth of Binary Tree


Single Number



Remove Linked List Elements



Remove Element



Delete Node in a Linked List

其中Remove Element到現在還是不太懂他題目在問什麼orz,如果說目標int array也要移除所有目標值,但我通過的程式碼也沒有完全移除阿,不太明白。

LeedCode:Remove Linked List Elements

題目:

Remove all elements from a linked list of integers that have value val.
Example
Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6
Return: 1 --> 2 --> 3 --> 4 --> 5
找到含有目標值的節點並刪除。
Delete Node in a Linked List中的Linked List定義相同

想法:

這題也卡了有點久,原本是想設一個tempNodePointer指向開頭或結尾的節點,檢查完有目標值就刪掉換下一個,但問題出在,如果沒有目標值,只是純粹換下一個,會把原本的節點給蓋掉。
所以後來選擇比較不直觀的遞迴解。

Accepted Solution:

C#
  1. public class Solution {
  2. public ListNode RemoveElements(ListNode head, int val) {
  3. if (head!=null) //該點為空直接傳回null
  4. {
  5. while(head.val == val) //如果該點含目標值
  6. {
  7. //刪掉該點
  8. if(head.next!=null)head = head.next;
  9. else {
  10. head=null;
  11. return null;
  12. }
  13. }
  14. //對該點的下一點做同樣的事
  15. head.next=RemoveElements(head.next, val);
  16. }
  17. else return null;
  18. return head;
  19. }
  20. }

LeetCode : Delete Node in a Linked List

題目:

Write a function to delete a node (except the tail) in a singly linked list, given only access to that node.
Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function.

在給定的Linked List下刪除指定節點,
Linked List定義如下(in C#)
  1. public class ListNode {
  2. public int val;
  3. public ListNode next;
  4. public ListNode(int x) { val = x; }
  5. }

想法:

因為是單向的,無法得知被誰所指定,索性把目標節點改的和他下一個一模一樣,C#就會把目標節點當垃圾收走啦,用題目的例子來說就是變成:1->2->4->4,原本的3所指向的物件就完全沒有參照而被收走了

Accepted Solution:

C#
  1. public class Solution {
  2. public void DeleteNode(ListNode node) {
  3. node.val=node.next.val ;
  4. node.next = node.next.next;
  5. }
  6. }

2015年7月21日 星期二

20150721 一些學習紀錄

原本想用Github搭配來記錄學習過程和在leetcode&codeeval上的解題思路,但比想像中要麻煩,還是先用blogger記錄吧。

首先是如何在blogger內嵌程式碼,參考網站
C#:
  1. using System;
  2. public static void main()
  3. {
  4. System.Console.Write("Hello Blogger!!");
  5. System.Console.ReadKey();
  6. }
效果不錯,使用上也頗方便!

今天把class的封裝看完了,get/set也練習了不少。

至於LeetCode還是卡在valid Number,不斷出現沒想到的特例... 看來還是欠磨練阿!(1359/1481)
目前遇到的例子:
46.e3,應該也是合理的數字,46*10^3=46000,沒想到e也可以接在小數點後面而疏忽了。
C#
  1. public class Solution {
  2. public bool IsNumber(string s) {
  3. bool haveDigits = false, Key = false,sign=false;
  4. s = s.Trim();
  5. for (int i = 0; i < s.Length; i++)
  6. {
  7. if (char.IsDigit(s[i])) haveDigits = true;
  8. else
  9. {
  10. switch (s[i])
  11. {
  12. case 'e':
  13. if (!haveDigits || i + 1 == s.Length || Key) return false;
  14. Key = true;
  15. break;
  16. case '.':
  17. if (Key || (i + 1 == s.Length && !haveDigits)) return false;
  18. Key = true;
  19. break;
  20. case '+':
  21. if (haveDigits || sign||Key) return false;
  22. sign = true;
  23. break;
  24. case '-':
  25. if (haveDigits || sign||Key) return false;
  26. sign = true;
  27. break;
  28. default:
  29. return false;
  30. //break; 用不到的break
  31. }
  32. }
  33. }
  34. if (!haveDigits) return false;
  35. return true;
  36. }
  37. }

明日再戰!