solidityで2次元配列を1次元配列にして返却する
solidityは現状多次元配列を返却できない。stringの配列も2次元配列扱いだから返却できない。
どうにかして数値データだけでも一撃で取得できないものかと下記のコードを書いてみた。
データをuint256に限定とかすれば一応、一撃で取得できる?これ実用的なのかな。
まだよくわかっていないけれど、viewの関数はgasが一切かからないからこれはこれでいいかも知れない。
solidityで2次元配列を1次元配列にして返却する
solidityは現状多次元配列を返却できない。stringの配列も2次元配列扱いだから返却できない。
どうにかして数値データだけでも一撃で取得できないものかと下記のコードを書いてみた。
データをuint256に限定とかすれば一応、一撃で取得できる?これ実用的なのかな。
まだよくわかっていないけれど、viewの関数はgasが一切かからないからこれはこれでいいかも知れない。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
pragma solidity ^0.4.18; contract returnTest { uint public catNum; mapping(uint=>uint[3]) public cat; function addCat() public{ cat[catNum][0] = catNum + 1000; cat[catNum][1] = catNum + 2000; cat[catNum][2] = catNum + 3000; catNum++; } function getAllCat() public view returns(uint[]) { uint[] memory store = new uint[](catNum*3); uint cnt = 0; for(uint i=0; i<catNum; i++){ store[cnt++] = cat[i][0]; store[cnt++] = cat[i][1]; store[cnt++] = cat[i][2]; } return store; } } |
solidityのgas消費量調査
例えばバブルソート実行時、
storage領域(メンバ変数的なとこ)を直接何回も書き換えるより、
memory領域で計算終わらせて最後にstorage領域にコピーした方がgasが安いことがわかった。
https://ethfiddle.com/Ge47VLSHtf
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
pragma solidity ^0.4.18; contract SimpleStore { uint[] ary; function swap(uint[] a, uint l, uint r) private pure { uint t = a[l]; a[l] = a[r]; a[r] = t; } function getBubbleSortedAry(uint[] a) public pure returns(uint[]) { uint len = a.length; uint i; uint j; for(i=0; i<len-1; i++){ for(j=i+1; j<len; j++){ if(a[j] < a[i]){ swap(a,i,j); } } } return a; } function test_getBubbleSortedAry() public view returns(uint[]){ return getBubbleSortedAry(ary); } function bubbleSortIndirect2() public { uint[] memory clone = getBubbleSortedAry(ary); for(uint i=0; i<ary.length; i++){ ary[i] = clone[i]; } } function bubbleSortIndirect() public { uint len = ary.length; uint i; uint j; uint[] memory clone = new uint[](len); for(i=0; i<len; i++){ clone[i] = ary[i]; } for(i=0; i<len-1; i++){ for(j=i+1; j<len; j++){ if(clone[j]<clone[i]){ swap(clone, i, j); } } } for(i=0; i<len; i++){ ary[i] = clone[i]; } } function bubbleSortDirect() public { uint len = ary.length; uint t; for(uint i=0; i<len-1; i++){ for(uint j=i+1; j<len; j++){ if(ary[j] < ary[i]){ t = ary[i]; ary[i] = ary[j]; ary[j] = t; } } } } function getArray() public view returns (uint[]){ return ary; } function setAryRandom5() public { uint length = 5; setAryReverse(length); } function setAryRandom8() public { uint length = 8; setAryReverse(length); } function setAryRandom10() public { uint length = 10; setAryReverse(length); } function setAryReverse(uint length) private { ary = new uint[](length); for(uint i=0; i<length; i++){ ary[i] = length-1-i; } } } |
Solidityでクイックソート
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
//Write your own contracts here. Currently compiles using solc v0.4.15+commit.bbb8e64f. pragma solidity ^0.4.18; contract SimpleStore { function test() public pure returns (uint[]){ uint[] memory a = new uint[](5); uint n = 5; for(uint i=0; i<a.length; i++){ a[i] = n - i; } quicksort(a); return a; } function quicksort(uint[] a) public pure { uint left = 0; uint right = a.length-1; quicksort_core(a, left, right); } function quicksort_core(uint[] a, uint left, uint right) public pure { if(right <= left){ return; } uint l = left; uint r = right; uint p = getPivot(a[l], a[l+1], a[r]); while(true){ while(a[l] < p){ l++; } while(p < a[r]){ r--; } if(r<=l){ break; } swap(a, l, r); l++; r--; } quicksort_core(a, left, l-1); quicksort_core(a, r+1, right); } function getA() public pure returns (uint[]) { uint[] memory a = new uint[](5); for(uint i=0; i<a.length; i++){ a[i] = i; } swap(a, 0, 4); quicksort(a); return a; } function getPivot(uint a, uint b, uint c) public pure returns (uint){ if(a > b){ if(b > c){ return b; }else{ return a > c ? c : a ; } }else{ if(a > c){ return a; }else{ return b > c ? c : b ; } } } function swap(uint[] a, uint l, uint r) public pure{ uint t = a[l]; a[l] = a[r]; a[r] = t; } function increment(uint[] a) pure public { for(uint i=0; i<a.length; i++){ a[i] = 1; } } } |
c言語でクイックソート
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 |
#include <stdio.h> #include <stdlib.h> #include <time.h> void dispArrayLine(int a[], int length, int dispTotal){ int total = 0; for(int i=0; i<length; i++){ total += a[i]; printf("%d", a[i]); if(i!=length-1){ printf(" "); }else{ if(dispTotal){ printf(" : %d", total); } printf("\n"); } } } void dispArrayList(int a[], int length){ for(int i=0; i<length; i++){ printf("[%d] : %d\n", i, a[i]); } } void resetArray(int a[], int length){ for(int i=0; i<length; i++){ a[i] = 0; } } void init(){ srand((unsigned)time(NULL)); } double getRandomDouble(){ return (double)rand() / RAND_MAX; } int getRandomInt(int min, int max){ double d = getRandomDouble(); int randomOffset = d * (max - min + 1); return min + randomOffset; } void setRandomIntForArray(int a[], int length, int min, int max){ for(int i=0; i<length; i++){ a[i] = getRandomInt(min, max); } } int getPivot(int a, int b, int c){ if(a > b){ if(b > c){ return b; }else{ return a > c ? c : a ; } }else{ if(a > c){ return a; }else{ return b > c ? c : b ; } } } int getMax(int a, int b, int c){ if(a > b){ return a > c ? a : c ; }else{ return b > c ? b : c ; } } int getMin(int a, int b, int c){ if(a < b){ return a < c ? a : c ; }else{ return b < c ? b : c ; } } void swap(int a[], int l, int r){ int t = a[l]; a[l] = a[r]; a[r] = t; } void quicksort_core(int a[], int length, int left, int right){ if(right <= left){ return; } int l = left; int r = right; int p = getPivot(a[l], a[l+1], a[r]); while(1){ while(a[l]<p){ l++; } while(p<a[r]){ r--; } if(r<=l){ break; } swap(a, l, r); l++; r--; } quicksort_core(a, length, left, l-1); quicksort_core(a, length, r+1, right); } void quicksort(int a[], int length){ int left = 0; int right = length-1; quicksort_core(a, length, left, right); } int main(void){ init(); int length = 30; int a[length]; int min = -9; int max = 9; setRandomIntForArray(a, length, min, max); dispArrayLine(a, length, 1); quicksort(a, length); dispArrayLine(a, length, 1); return 0; } |
Javaでひさびさのポリモフィズム動物園(多態性動物園)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
import java.util.*; public class Main { public static void main(String[] args){ List<Animal> zoo = new ArrayList<Animal>(); Animal a; a = new Cat(3); zoo.add(a); a = new Dog(5); zoo.add(a); a = new Mike(7); zoo.add(a); Breeder b = new Breeder(); b.breed(zoo); } } class Breeder { public void breed(List<Animal> animals){ for(Animal a : animals){ a.cry(); } } } abstract class Animal{ public int age; public Animal(int age){ this.age = age; } public abstract void cry(); } class Cat extends Animal{ public Cat(int age){ super(age); } @Override public void cry(){ System.out.println("ニャー(" + this.age +")"); } } class Dog extends Animal{ public Dog(int age){ super(age); } @Override public void cry(){ System.out.println("ワン(" + this.age +")"); } } class Mike extends Cat{ public Mike(int age){ super(age); } } |
c言語で配列の要素数を取得するマクロ
c言語で配列の要素数を取得する関数は作れないと思っていたが、
関数じゃなくてマクロにしたら実装できたっぽい。
これで配列の先頭アドレスを渡す各種関数に配列のサイズを渡さなくて済みそう。
配列の要素数をその都度計算する分、引数で渡すのに比べて
パフォーマンスは低下するけれど気にするほどのことではない。
GET_ARRAY_LENGTHというマクロ
1 2 3 4 5 6 7 8 9 10 11 12 |
#include <stdio.h> #include <limits.h> #define GET_ARRAY_LENGTH(a) (sizeof(a)/sizeof(a[0])) int main(){ int arr_int[] = {INT_MAX, 0, -(INT_MAX-1)}; printf("arr_int length : %ld\n", GET_ARRAY_LENGTH(arr_int)); char *arr_str[] = {"a", "あいう", "あ0いうbc", "", "\0"}; printf("arr_str length : %ld\n", GET_ARRAY_LENGTH(arr_str)); } |
c言語でバブルソートの練習
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
#include <stdio.h> #include <stdlib.h> #include <time.h> #include <limits.h> void init(){ srand(time(NULL)); } double getRandomDouble(){ return 1.0 * rand() / INT_MAX; } void resetArray(int *a, int size){ for(int i=0; i<size; i++){ a[i] = 0; } } int getRandomInt(int min, int max){ double d = getRandomDouble(); int randomOffset = (int)(d * (max - min + 1)); int randomInt = min + randomOffset; return randomInt; } void dispArrayList(int *a, int size){ for(int i=0; i<size; i++){ printf("[%d] : %d\n", i, a[i]); } } void dispArrayLine(int *a, int size){ for(int i=0; i<size; i++){ printf("%d", a[i]); if(i < size-1){ printf(" "); }else{ printf("\n"); } } } void setRandomForArray(int *a, int size, int min, int max){ for(int i=0; i<size; i++){ a[i] = getRandomInt(min, max); } } void swap(int *a, int l, int r){ int t = a[l]; a[l] = a[r]; a[r]= t; } void bubblesort(int *a, int size){ for(int i=0; i<size-1; i++){ for(int j=i+1; j<size; j++){ if(a[i]>a[j]){ swap(a, i, j); } } } } int isSorted(int *a, int size){ for(int i=0; i<size-1; i++){ if(a[i+1] < a[i]){ return 0; } } return 1; } int main(){ init(); int size = 20; int a[size]; setRandomForArray(a, size, 0, 9); dispArrayLine(a, size); bubblesort(a, size); dispArrayLine(a, size); } |